views:

126

answers:

6

In my .NET web app, I keep basic user info in a user session object. I also usually keep a director class in the session; which is basically just has info about whatever thing it being worked on on that screen (like a customer id).

I am trying to keep from adding a ton of sessions. I also want to make sure at any given time ONLY the sessions that are necessary are in memory.

This means I need an effective way of managing my session variables. Any suggestions?

A: 

My suggestion: Don't use session variables. Store everything in a database.

Shawn Simon
-1 - You do NOT want to store temporary information like session info in a database.
JonH
It's not an either/or choice. You can persist sessions to db, and this is in fact my preferred approach.
RedFilter
Unless you've got multiple web servers, in which case you do what you gotta do. (There are still better options, even then.)
Patrick Karcher
@JonH that's misleading because you can store the session itself in a database as opposed to in memory. I believe your statement meant to convey you store transient information in a user session as opposed to in a permanent data store like a database.
Chris Marisic
+1  A: 

Two things:

1 - You should not be storing so much in session that managing memory is a concern. I.e., don't store objects in session, store pointers to things, e.g., rather than an instance of User just store the UserID. If you need to, you can add caching of retrieval of info, but that should be in a caching layer separate from sessions.

2 - Use database sessions, so that there is no concern about server memory, and so that you can add more web servers easily if desired (note, StateServer gives you this capability as well). Additionally, this lets you recycle the app pool without users losing their session. This is the main reason I do it - it lets me deploy on the fly.

The reason to treat sessions so delicately, is that they hang around after a user's last request, typically for 10 to 20 minutes. So, requests from many different sessions can use up large amounts of server memory if you are storing large objects in session. Doing even crazier things, like storing database connections in session, can result in you using up all available database connections, just because so many are hanging around in memory waiting for the session to expire.

Ideally, there is no "managing" of sessions required.

RedFilter
+1 much better advice, store lightweight data rather then actual objects / datasets/ tables, etc.
JonH
A: 

I think you're misunderstanding sessions in ASP.NET. You do not explicitly manage them (although you could, you would rarely want to) they are implicitly created and destroyed by ASP.NET and IIS. Every user is given a session.

Now anything you store inside a users session is stored in memory on the server so if you routinely place large objects in each users sessions this will cause the memory to grow rapidly leading to performance and scalability issues.

The only data you need to store in the session is transient data that you want to be available across different page requests that you want to be secured that it is not available to the client in a cookie or similar construct.

However reading what you're doing this is most likely not needed. Since you are working with a specific page and "director" functionality this would most likely be fitting to place on the page in the viewstate as an intermediary data store.

Chris Marisic
A: 

There is no wright answer. It depends on the number of concurrent users, on the size of your memory. Keeping things on session is faster than on a database, if you have your session variables in proc. I usually try to keep just things that I know the user might need during a specific task, or, like you said, information of the current user.

VinTem
A: 

What I normally do is only keep the id of an object in Session and keep the data in a caching layer in front of the database. That way, you keep your session fairly small but most data can still be retrieved efficiently if the item is in cache. This has usually worked well for me.

CountCet
A: 

My suggestion is:

  • Wrap the session access into a IPerSessionCache interface
  • Have a concrete implementation of this interface
  • Use an instace of the concrete class in the code to get/set session data
  • By this, then you have the freedom to clean up the instance of IPerSessionCache when the session ends
  • The code will not need to know where the IPerSessionCache actually stores the data (ie. it could in the Session or in a database or in a cookie etc.)
  • You would have better control on the lifetime of the IPerSessionCache especially if you use a DI container for managing & creating the instance

HTH.

Sunny