views:

267

answers:

5

I'm building an ASP.Net website. I have a "cart" class which stores the items in the users cart. I don't want to re query the database every time the page reloads to populate the cart items stored in this object. Is the best way to store/persist instantiated objects by putting them in a session and store the session to a database (we're on SQL Server 2k8)? It seems like that's what most are recommending from reading other posts on StackOverflow. Our site has a pretty high amount of traffic, so its easy to imagine 1000's of these objects being active at any given time.

I'm new to building ASP.Net websites. Is it common practice to persist user objects (not just simple variables in a session or cookie, but class objects)... also along the lines of persistent objects, I plan on creating a static class which stores commonly used site-wide data such as a List of U.S. states... are there any pitfalls with doing this? I don't want to shoot myself in the foot.

Update:

We are in a farm environment so storing sessions in a daatabase seems out of the question... if one server goes down we roll over to another... in which case the session data may be lost. We were considering using a separate server for storing sessions, which would work in our farm environment but I'm iffy about storing that many instantiated objects in memory.

+1  A: 

You may want to consider looking at a new Microsoft technology which they call AppFabric. It contains a distributed cache capability (formerly known as Velocity). The problem with persisting your session state to SQL is, of course, you have a database hit every time you access your session state. Problem, of course, with using the Session object is that it is only available to that particular server which breaks down if you are in a farmed environment. Velocity provides a distributed cache (which is also capable of working fairly seamlessly with ASP.NET Session data), which is an in-memory cache distributed across some number of machines and which all of your servers can have access to.

Steve Elmer
check out http://msdn.microsoft.com/en-us/windowsserver/ee695849.aspx
Steve Elmer
Hrmm well that answers that... we do have a farm environment, so storing the data in sql server seems out of the question. I was discussing this with a co-worker and we were considering having a seperate server to handle sessions (without a database)... which I'd be worried about memory allocation since we'd be storing several objects per user in there. I'll take a look at AppFabric
Chris Klepeis
No, sql is, I believe, the standard for storing session data in a farmed environment. With your data in SQL it will be accessible from any machine in the farm. There is, though, the overhead of a database hit whenever you need to get to your session data.
Steve Elmer
Storing in a SQL server is out of process, so you have no issues on a web farm. That is EXACTLY what it is designed for. If you want a separate server to handle session without a database then you are wanting a 'StateServer' which is also out of process and works great on a web farm.
Clarence Klopfstein
It might, actually be a better starting point for you as I think it might be quicker to get things up and running. Using a separate server to store your session state is also a possiblity - but that solution doesn't scale well. I don't know much about AppFabric - I am only just beginning to look into it myself - but I think it may be a better solution over the longer term as it pushes the state up into memory, it is scalable, and it is accessible from which ever machine a web request happens to land on.
Steve Elmer
+2  A: 

Session is likely your best option.

Since you are using SQL as your Session holder it will be out of process, so you will have it available on a web farm without issue. Though, you will still be having a database hit every time you reference that object. However, it is a highly efficient database hit.

Just be sure to make sure your Cart class is 'serializable' otherwise it will blow up going to Session.

Clarence Klopfstein
Is this essentially what NHibernate does? https://www.hibernate.org/343.html ... would anyone recommend it as a solid product?
Chris Klepeis
I'll add more to this to make sure you understand.Yes, if your Session server goes down, you lose all of that session data. It is very similar to a Database server. You can add a database (there is a script out there) to hold the session data for you. It could be on its own server, or the same server as the rest of your application data.
Clarence Klopfstein
I haven't used NHibernate, so I can't comment.
Clarence Klopfstein
StateServer is also a good option for session mode.
Josh Stodola
+1  A: 

Since you said that you don't want to requery the DB each time a page loads, Session state would be a poor choice -- since that's exactly what it does (assuming you're using SQL mode, since InProc mode won't work for a web farm). In fact, there are normally two round-trips to the DB for each request: one at the beginning to read the session object and update the session expiration time, and another at the end to update it. Sessions also impose locks on your pages while they're active, which can be an issue for sites that use Ajax or frames or where users often use multiple windows.

In general, you will be much better off from a performance and scalability perspective by storing the objects in SQL Server yourself. With that approach, you can do things like cache the objects using a SqlDependency or SqlCacheDependency to avoid round-trips. In a web farm, it also often helps to use cookies to help ensure that everything is in sync, since there can be a slight delay from when the DB is updated to when the cache entries are cleared on all servers by way of notifications.

In case it helps, I cover these types of issues in detail in my book: Ultra-Fast ASP.NET.

RickNZ
A: 

This may be a case of premature optimization.

In my opinion, it's hard to create a quality web site if you design it around using session state. HTTP is "stateless," and although there are abstractions designed to disguise this fact (such as the ASP.NET Session), you will often be confronted with the truth. The Session object is an OK tool for doing in-memory caching, but you should never count on it being reliable. In other words, you can use it to optimize code, but you'll still always also need the code to do the full database retrievals as a fall back.

In-SQL storage of Session is a way to try to work around server farm issues, but why bother that if you're trying to avoid the database in the first place? Keep in mind that although you may be repeating queries for the same shopping cart data across requests, the SQL server itself can do a lot of the caching and optimization for you. It may not be as slow as you think.

As far as static data goes, use caution. App pool recycling can sometimes break this in-memory data, and you have to be very careful that access to static data that needs startup initialization is reentrant.

Jacob
A: 

Can you use sticky sessions (affinity) on your web farm, and stick stuff into session?

http://msdn.microsoft.com/en-us/magazine/cc163844.aspx

mgroves
Sticky sessions are a bad, bad idea. They significantly interfere with things like scalability, predictability and capacity planning, while also eliminating one of the features of web farms, which is the ability for one server to fail without user disruption.
RickNZ