I work on a classic ASP web site that uses ASP session state to hold sate information. We use the sql database implementation of ASP session state.
We are having problems where sessions are being left locked and then subsequent requests to that session pile up into big queues that are affecting our performance. I don't expect you to be able to fix this for me but maybe someone could give me an overview of session state, as I don't think that i fully understand it.
None of our pages are marked as read only so all of our requests to the session database are exclusive (TempGetStateItemExclusive3); which in turn places a lock on the session.
I understand that if a modification to session is made that we update the session in the database (TempUpdateStateItemShort) and part of that process removes the lock.
I also understand that if we abandon a session that the lock is removed by (TempRemoveStateItem).
I also understand that that a sql agent job occurs periodically to delete expired sessions.
What I don't understand is how we abandon a session or how we release locks on sessions that we have locked through a Get but dont update?
I have read the following to get this far in my understanding http://msdn.microsoft.com/en-gb/library/aa478952.aspx and http://msdn.microsoft.com/en-us/library/aa479041.aspx
As always any help will be gratefully received and appreciated.
I have spent some more time looking into this and i think that i have figured it out.
Abandoning a session is an explicit action, Session.Abandon()
Releasing a lock is an implicit action
On the page_load event a call to TempGetStateExclusive3 is made to get the session object. Exiting the page_load implicitly calls TempReleasStateItemExclusive. As a developer you are only in control of abandoning a session, the locking is handled for you by the framework.
This does not fix my issue with sessions being left locked. But at least now I know how sql server session state should work.
Thanks
Related
In this question there's a comment with a few upvotes that states:
InProc session state is known to be highly unstable under load. If it's abused (happens all the time), then Session["foo"] = null will perform better than Session.Remove["foo"]. The garbage collector should clean up the mess of excessive session variables
This concerns me as all of my web apps make heavy use of session state (account info, baskets, payment details, user preferences etc.).
I can't seem to find any evidence to back up this claim, can someone debunk this or explain why this is correct. Am I wrong to be storing such info in session? I'm not looking for a pros and cons of InProc vs SQL, I'm aware of the differences.
All of my apps run on a single or dedicated webserver so I've never seen any benefit or point in moving to SQL for session state.
InProc Session State is stable and you don't have to worry about it. I don't know why he called it unstable but I guess he might have thought one of the following reasons while commenting:
If your application gets too much load; when you scale it, you have to use sticky session (for InProc SessionState) to redirect the requests to the same server for a client otherwise session object would not persist.
If an application has memory leaks or inconsistencies, heavy load will most probably trigger the application to reset and this will cause all the session data be lost so that current users' active pages might get errors since their session datas are lost.
Session object is locked out for the entire request (for that user only) to prevent multiple pages to write into the session so that if concurrent requests are made for example, they have to wait for each other to write data into Session. But it happens both in SQL and InProc SessionState.
I saw banking applications which work with InProc SessionState and there is nothing unstable about it.
After a previous post about an issue with Session State being locked on every request (normal behavior for Asp.Net), tried fully disabling Session State (). This, in fact, disables the Session object and throws exceptions if try to use it. However, as stated in the named post, all requests are still serviced in a serialized fashion. This is, a second "simultaneous" request doesn't get served till previous gets finished served. Related documentation states that disabling Session State avoids the lock in the session but, in my case, my requests are still serviced serially.
This is not MVC.
This is my previous post Custom handler processes multiple requests serially and not simultaneouslly
Any help would be appreciated.
Turns out this always happens inside the developer environment (cassini). When dissabling session state there is no possible access to the Session object but it seems to exists a lock request somewhere.
Debugging in IIS this doesn't happen.
Hope this help.
I am trying to "log" forcefully when a user has been inactive and or the session has ended (either by inactivity or more importantly, when the browser has closed).
I dont want to use any silly AJAX solution to perform a post every few minutes for "im alive" or call when the browser is closed.
I was under the impression that if you store an object in Session, and you reach the Session_End event, then you will not be able to gain access to anything stored in Session as its ended.
But from some testing I have done, it appears that this is probably the last chance you can obtain access to the object.
Could this be true? is it reliable?
using ASP.NET 4.0 here.
Typically there are two things done.
The first is that a javascript timer is added to the client, not as a heartbeat, but rather as a reminder. If they are close to the session ending, then it simply says "session is about to end. Are you still there?" If so, then it does the "silly" post to ensure the server keeps the session going. This is purely to be nice to your users.
The second (and point of your question) is that you put something in session_end in order to clean up the session. Reliable? well.. most of the time.
Session_End won't run if the app pool is recycled. However, assuming the app pool is ok then yes it will execute when the session expires. The app pool can be recycled for a LOT of reasons ranging from the app crashing to exceeded memory usage to simply because it's been a while since the last reset. This is configurable in IIS.
Would I trust session_end? No. Not 100%. Of course, I wouldn't put anything inside of a session object that would require me to trust it 100% anyway.
For logging the timeout You can use the Global events to log at timeout. See this link for order of events http://www.techrepublic.com/article/working-with-the-aspnet-globalasax-file/5771721
Are there any pre-conditions before storing any objects in session state.
I mean when will I not be able to insert an object in session state.
This was an interview question that was asked to me.
What could be the possible reason for not being able to store an object in session state?
Here are some that should be considered:
If it has more session data, then more memory is consumed on the web server, and that can affect performance.
It won't work in web garden mode, because in that mode multiple aspnet_wp.exe will be running on the same machine.
And if the appdomain or worker process (aspnet_wp.exe) restart/recycles very often then its not a good idea to use it
and it is gathered from here ... hope it answer your query ...
There are places in the asp.net page request life-cycle that you do not have access to the session state yet due to the lack of a valid user session such as Application_Authorize where we do not have an authenticated user yet, so Session will be null. The actual implementation of the Session store shouldn't really be a concern, neither should how the data is serialized.
I have an iframe keep alive (iframe that hits a page, defibrillator.aspx, on my site every few minutes to keep the session alive) on my masterpage for an asp.net app. This works most of the time but every so often my session variables return null during the page load on my defibrillator page. At first, I thought the session was being timed out by the server for some reason so I put some logging into the Session_End event in the global.asax but it was never hit.
Any ideas what could cause the session to be lost.
Many things can cause session to be lost. An AppPool recycle, iisreset, the client could lose its session cookie, etc. Without knowing more it is difficult to tell what is the problem.
If session is so critical that you poll the application to keep the worker process from sleeping perhaps you ought to look into persisting your session state to SQL Server.
Peter Bromberg outlines the primary reasons for ASP.NET session timeouts on his blog.
I had this same sort of problem, storing a shopping cart state in Session but having it randomly return null instead. I think I found the answer on Bertrand Le Roy's blog, which seems to work for me:
Session loss problems can also result
from a misconfigured application pool.
For example, if the application pool
your site is running is configured as
a web farm or a web garden (by setting
the maximum number of worker processes
to more than one), and if you're not
using the session service or SQL
sessions, incoming requests will
unpredictably go to one of the worker
processes, and if it's not the one the
session was created on, it's lost. The
solutions to this problem is either
not to use a web garden if you don't
need the performance boost, or use one
of the out of process session
providers.
Blog
If the chosen persistence mechanism is InProc then it can be triggered by many things. Totally counter-recommended for a production environment.