There are many cases in which storing state information on the client is either impractical or just plain impossible. In a previous article, I outlined state management techniques such as using ViewState, hidden form fields, cookies, and query strings to store and forward state between server calls. But perhaps you need the information about the state of an application designed to be shared between multiple clients to be stored centrally rather than passed back to each of the clients; or, you may want information about the state of a transaction to be accessible from multiple clients. What if your users need to be able to create a shopping cart on one machine and finalize the purchase at a later date on a different client machine? In that case, the cart information has to be stored on the server.
Let’s look at the three options for server-side state management you can use when architecting your .NET applications: application state, session state, and databases.
Application state is a global storage mechanism accessible from all pages in the Web application and is useful for storing information that needs to be maintained between server round-trips and between pages. You should use application state to store any piece of information or data that affects the behavior of the application or needs to be shared between multiple user sessions (e.g., shared lists or catalogs, default user options, and hit counters). Application state is easy to use and probably familiar to ASP developers, which allows developers to implement it quickly. Since application state is accessible to all of the pages in an application, storing information there means that you need only one copy of the information in memory on the server rather than duplicating the information in session state, cookies, or other state mechanisms for each user.
To understand the potential benefits and pitfalls of application state, you also need to more tightly define how the global scope of application state is implemented. You should be aware that any variables stored in application state are global only to the specific process in which that application runs. If you have multiple processes in your application, each process will have its own set of values. Because of this, you cannot design an application that uses application state to store unique values or update global counters in Web gardens or Web farms. Furthermore, since the data stored in application state depends on the process for its memory storage, the data will be lost if the Web server process shuts down due to a planned shutdown or server crash.
Finally, you’ll have to be careful about the amount of memory you consume when using application state. Application state is an ideal place to store small to medium lists used by multiple pages or users (e.g. a list of states for drop-down lists or header and footer strings that should appear on every page). However, allocating large chunks of server memory can adversely affect the performance of the server and all applications running on that server.
Like application state, using session state involves storing information in server memory. But unlike application state, the server stores a different copy of the session variables for each browser session. The server differentiates between sessions by assigning an internal Session ID. Session IDs are unique across time, meaning that if a user on a site closes the browser, reopens it, and navigates to the same site, that user will be considered a new user and assigned a new Session ID. Using the Session ID, the server can access a unique key-value dictionary structure that stores session-specific information that persists between server round-trips and page requests.
For existing ASP developers, the session state facility is familiar. But even new ASP.NET developers can easily implement session state just by assigning values like this: Session(“Foo”) = “Bar” where the variable Foo has the value Bar. Developers also have access to session management events raised by ASP.NET and can raise their own events based on session usage.
Session state is the preferred state mechanism for most user-specific, single session, nondurable scenarios, but you must still use it carefully. Because session state variables stay in the server’s memory until they are either removed or replaced, excessive use of session state variables that contain blocks of information like large datasets may adversely affect Web server performance as server load increases. This affects not only the Web application where the variables are stored, but any other applications running on the same server.
Using a database to store state
In many cases, state information must be stored for long periods of time or must be preserved even if the server restarts. For this reason, using database technology to maintain state is a common practice. Using databases to maintain state also makes sense when the amount of user-specific information that needs to be maintained for a particular session is very large, but doesn’t need to be kept in memory at all times.
Storing state information in a database also gives you an additional layer of security. Hackers attempting to access state information for a running application have to get through the Web server’s security and also crack the authentication and authorization mechanisms of the back-end database. Databases also have the advantage of potentially unlimited storage and persistence: Information in the database can be stored indefinitely and isn’t subject to the availability of the Web server. You can also ensure the integrity of information stored in a back-end database by using the database server’s internal facilities for maintaining data, like triggers, referential integrity, transactions, and so on.
For example, using the database’s transaction management capability makes recovering from errors easier and more reliable than trying to maintain transaction information in session state. Any other application, report writer, or other tool can access database state information. These tools don’t have access to information stored in application or session state. If you want to create tools that monitor or report on Web activity, you can do so by accessing the database state information from these tools.
Implementing state management using a database generally requires a more complex configuration and the management of another layer of security. Given the additional processing and security overhead, and the fact that the data is not stored in memory like application and session state, accessing state data in the database will be considerably slower than in-memory alternatives. You’ll have to be careful when designing a state management database to emphasize access speed to ensure that database queries will not adversely affect your application’s performance.
Server state management considerations
Application state is best for single-server scenarios where you need common information for multiple users or pages. Session state can be used for most multiserver scenarios where you need to store a moderate amount of information per user, and data persistence doesn’t need to span multiple sessions. And use the database to store large amounts of infrequently accessed state information or state information that has to persist between multiple sessions.