currently we are using Sessions to store datatables in our pages so that we don\'t have to make Database hits to get the same datatable again and again. But my worry is that
As a general rule of thumb I would say don't use session. I haven't had to use session for a long time. As soon as you move into a web farm situation session either gets a lot slower or a lot more complicated or both.
Whether you will get away with it or not really depends on how much data you are storing in session, and how many users will be active within the session timeout period.
There are a lot of caching and in memory database options available today that may be a better option. Finally, while the solution as described sounds questionable, I wouldn't optimize the existing solution until you have actually measured a problem.
If your datatable has smaller number of records and it does not contain sensitive data then you can use ViewState as well but data should be smaller as this approach will serialize the data and store it at client side and then gets the data from client side to store at server side.
If you can't increase memory on the web server then the obvious answer is to not store it in session state and get it from the database every time.
The problem with this is what impact will it have on your database? Are you just moving the problem from the web server to the database server?
It is much easier to scale out web servers than it is to scale up/out Databases (and often cheaper if you're using something like SQL Server)
It is preferable to store "commonly used" data in Memory; that's good logic. However "Session" means that it exists for the life of that Session, and hence that user. Secondly, pending the user "Session" life, as you already said, this could be consume valuable resources on the Server Side.
What you may want to consider using is the "Cache" object, as it serves the same purpose with "Expiration".
DataTable users = new DataTable();
if (Cache["users"] == null)
{
// users = getUsers(customer);
Cache.Add(“users”, users, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 60, 0), System.Web.Caching.CacheItemPriority.Default, null);
}
else
{
sers = (DataTable)Cache["users"];
}
There are many ways to re-use memory in .NET (1) ViewState (2) Cache (3) Session (4) Cookies
But I would go for the "Cache" object.
This is dependent on what is being stored in the datatables. In any case, I would use the ASP.NET Cache to store these datatables for the following reasons.
Cache has an expiry, which means you can automatically remove it based upon a sliding or absolute expiry timed value
Cache will automatically be removed if the processes memory "pressure" is too high.
You can make a cached item specific to one user, or global to all users based upon its key
for example:
// personalized cache item
string personalCacheKey = string.Format("MyDataTable_{0}", (int)Session["UserID"]);
DataTable myPersonalDataTable = (DataTable)Cache[personalCacheKey];
if (myPersonalDataTable == null)
{
myPersonalDataTable = database.dosomething();
Cache.Insert(personalCacheKey, myPersonalDataTable, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0)); // 30 minutes
}
// global (non user specific) cached item
string globalCacheKey = "MyDataTable";
DataTable globalDataTable = (DataTable)Cache[globalCacheKey];
if (globalDataTable == null)
{
globalDataTable = database.dosomething();
Cache.Insert(globalCacheKey, globalDataTable, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0)); // 30 minutes (again)
}
The issue that you have now, however, is if the underlying data gets updated, and whether it is acceptable for your application to present "old" cached data. If it is not acceptable, you will have to forcibly remove an item from cache, there are a few mechanisms for that.
You can setup a SqlCacheDependency (which I have never personally used), or you can just clear out the cached object yourself using Cache.Remove(cachekey)
.