Correct use of nhibernate session - c#

i have a client server application, the server uses nhibernate.
i wanna know how should i use the session?
per call?
per client?
single?
other way?
and how can i keep the session cache in the server ?
and also i wanna know if the session is thread safe?

You should use one session per unit of work. If that includes multiple operations, so be it.
Use the session.BeginTransaction() to wrap the unit of work and commit once all the items are done.
Sessions are NOT thread safe, but the session factory is (which you definitely want to keep around).
NHiberate has various cache options for data, but the sessions are meant to be used and disposed.

Normally it's done one per request. You can create HttpApplication, which opens the session at the beginning of request and closes at the end of request (example).

Per call should be the usual solution

There really is no one right answer to the question of session lifetime. You can make any session lifetime work, it depends on your requirements. Sessions are not thread safe, but session factories are.
To keep the cache around, you need to keep the session around. It is likely to be fairly challenging to keep the cache around and keep the cache correct in anything but simple single user, single process applications.

There's a great example I've used from NHibernate Best Practices.
The code example uses a session per ASP.NET request.

Related

Can I have two Cassandra Sessions in C# backend application?

I need to talk to two Cassandra clusters in my backend at stable environment. However, in beta I have only one cluster and it's config is duplicated, so during startup we create two sessions.
Is it ok to have two sessions for one cluster?
Also we have multiple keyspaces, but only one connection for them. Should I make new session for each keyspace?
I see that session should be singleton, but I think it's not a demand, but a recommendation.
The recommendation to only create and reuse a single session per application is because session creation is very expensive.
Each time a session is created, the driver has to go through its standard initialisation process and open connection pools to every node in the cluster. Apart from the significant increase in memory usage, this will slow down your application for no benefit.
It makes no sense to create a session for each keyspace since the session can handle thousands of requests concurrently. All you need to do is to specify the keyspace when referring to a table in the query, for example:
SELECT ... FROM keyspace_name.table_name WHERE ...
As you pointed out, there is no technical barrier that prevents your application from creating multiple sessions. But there is also no benefit to doing so, just a lot of disadvantages so we don't recommend it. Cheers!

Access differences between cache and session in ASP.NET MVC

I'm writing an ASP.NET MVC5 Application, I know that the actions where session["foo"] = bar are ran sequentially, now to avoid this, i want to store some informations into a MemoryCache object and not in session, but my doubt is: Is the cache managed like the session? So the actions where i put ObjectCache.Set("foo", bar, null) are ran sequentially like for session?
I know the scope difference between cache and session but for me and in this case it's not important.
Thank to everyone
I understand that you try to avoid the session lock on the page.
The cache is not lock the full page access so the answer is that the cache is not run sequentially.
There are two kind of cache, one in memory that use static dictionary to keep the data and one that save the cache on database, that use files to save the data. Both of them locks the data only for the period of read/write, while the session is lock the full access on the page from start to the end of it.
So use cache, but close the session on the page you have this issue. Also have in mind that if you use web garden then the cache on memory can have multiple different data because memory cache have its own static space on each pool.
Also the session is different for each user, the cache is the same for all users.
some more to read : ASP.NET Server does not process pages asynchronously
I think the term you are looking for is thread safety - especially around concurrent access, typically writing.
Seems that according to MSDN, System.Runtime.Caching.MemoryCache is indeed thread safe. See also: Is MemoryCache.Set() thread-safe?

Does the "session per request" pattern take advantage of the cache? ("Session per session" or "Session per request")

I build a new application from scratch this days in a web application.
(The technologies are Asp.Net and the ORM I'm using is Entity Framework. if it matters)
I'm uncertain if the widely used pattern session per request is really a good one.
As I see it, the advantage of the pattern is that the cache isn't increases until the database session crash\ being too big and thus inefficient.
But isn't a new session for every request is too much? It means every server call reset the cache, even simple ajax request like auto-complete has a brand new cache, in fact for every key stroke the cache resets.
The chances you will query the same object-entity-row in one request is small.
Isn't Session per session is a better pattern? it has both the advantages meaning
The cache won't grow for ever.
The cache can actually be used...
So... Why is session per request is so widely used and session per session is not?
Clarifications:
When I wrote ORM session it applies both to NHibernate's session and EntityFramework's DbContext.
I do mean to flush-commit-SaveChanges of the session\dbcontext on each request.
Session per request pattern is more natural and robust for using with ORM. It has smaller chances to get dirty entities and has more predictable resource management.
If I got you right and you mean DbContext instance under Session than Session Per Session can be used only in application without data modification, otherwise you would get unexpected data submitting by a request while other request performs data modification. Also I'm not sure Entity Framework context is thread safe - while processing requests is multithread.
I not totally sure but I think Entity Framework doesn't use cache (== identity mapping) as wide as you expect. On selecting entity set it queries database even if all data are in cache - it can only avoid constructing new entities but using existing ones from identity map.
For caching there are other solutions and they are better.
For me, it all about providing consistency by constraining a unit of work to a single request. I'm not sure how a session per session would work when things go wrong.
For example, what would you do if several requests have been handled and then you get an optimistic concurrency exception on the commit? you could have several merge conflicts at that point.
So a session per request just limits your conflict exposure and makes unit of work on the request scope.

Should I use sessions?

I am designing an online time tracking software to be used internally. I am fairly new to c# and .NET though I have extensive PHP experience.
I am using Windows Forms Authentication, and once the user logs in using that, I create a Timesheet object (my own custom class).
As part of this class, I have a constructor that checks the SQL DB for information (recent entries by this user, user preferences, etc.)
Should I be storing this information in a session? And then checking the session object in the constructor first? That seems the obvious approach, but most examples I've looked at don't make much use of sessions. Is there something I don't know that others do (specifically related to .NET sessions of course)?
EDIT:
I forgot to mention two things. 1. My SQL DB is on another server (though I believe they are both on the same network, so not much of an issue)2. There are certain constants that the user will not be able to change (only the admin can modify them) such as project tasks. These are used on every page, but loaded the first time from the DB. Should I be storing these in a session? If not, where else? The only other way I can think of is a local flat file that updates each time the table of projects is updated, but that seems like a hack solution. Am I trying too hard to minimize calls to the DB?
There is a good overview on ASP.NET Session here: ASP.NET Session State.
If you don't have thousands of clients, but need "some state" stored server-side, this is very easy to use and works well. It can also be stored in the database in multi server scenarios, without changing a line in your code, just by configuration.
My advise would be not to store "big", or full object hierarchies in there, as storing in a session (if the session is shared among servers in a web farm in a database for example) can be somewhat costy. If you plan to have only one server, this is not really a problem, but you have to know that you won't be able to easily move to a multiple server mode easily.
The worst thing to do is follow the guys who just say "session is bad, whooooo!", don't use it, and eventually rewrite your own system. If you need it, use it :-)
I would shy away from session objects. And actually I would say look into .net MVC as well.
The reason I don't use the session is because I feel it can be a crutch for some developers.
I would save all of the information that you would have put into a session into a db. This will allow for better metrics tracking, support for Azure (off topic but worth mentioning) and is cleaner imo.
ASP developers know session state as a great feature, but one that is somewhat limited. These limitations include:
ASP session state exists in the process that hosts ASP; thus the actions that affect the process also affect session state. When the process is recycled or fails, session state is lost.
Server farm limitations. As users move from server to server in a Web server farm, their session state does not follow them. ASP session state is machine specific. Each ASP server provides its own session state, and unless the user returns to the same server, the session state is inaccessible. http://msdn.microsoft.com/en-us/library/ms972429.aspx
One of the main problems with Session is, that by default, it is stored in memory. If you have many concurrent users that store data in the session this could easily lead to performance problems.
Another thing is that application recycle will empty your in memory session which could lead to errors.
Off course you can move your session to SqlServer or a StateServer but then you will lose on performance.
Look into the HttpContext.User (IPrincipal) property. this is where user information is stored in the request.
Most people avoid session state simply because people like to avoid state in general. If you can find an algorithm or process which works all the time regardless of the previous state of an object, that process tends to be more fool proof against future maintenance and more easily testable.
I would say for this particular case, store your values in the database and read them from there any time you need that information. Once you have that working, take a look at the performance of the site. If it's performing fine then leave it alone (as this is the simplest case to program). If performance is an issue, look at using the IIS Cache (instead of session) or implementing a system like CQRS.
Session State Disadvantage
Session-state variables stay in memory until they are either removed or replaced, and therefore can degrade server performance. Session-state variables that contain blocks of information, such as large datasets, can adversely affect Web-server performance as server load increases. Think what will happen if you significant amount of users simultaneously online.
NOTE :- I haven't mentioned the advantages because they are straightforward which are : Simple implementation, Session-specific events, Data persistence, Cookieless support etc.
The core problem with sessions are scaleability. If you have a small application, with a small number of users, that will only ever be on one server, then it may be a good route for you to save small amounts of data - maybe just the user id - to allow quick access to the preferences etc.
If you MAY want multiple web servers, or the application MAY grow, then don't use session. And only use it for small pieces of information.

How to handle NHibernate sessions in an ASP.NET WebForms application?

I see there are 2 possible scenarios as to the session handling:
Open one single ISession per request. Open it at request start and close it at request end.
Open one ISession per conceptual "unit of work". Many sessions are created for a request.
The approach #1 is the one I'm doing now. I'm a little bit worried about it because, although it works, it's a little bit difficult to debug. For instance, I have an object not being saved (even though I ordered it to) and I'm having trouble debugging since there's a LOT of things happening during a complete request life-cycle.
The approach #2 seems to be the standard best-practice (not sure about ASP.NET) and I'm sure it's pretty easier to debug. The problem I see is about inter-session communication. For instance: My Page class holds a reference to the User, which is a persistent object. Many of the operations receive the user as parameter. As the user belongs to a different session, I can't pass it as a parameter.
I'm biased to #2, but I don't know if it's the best practice, nor how to deal with cross-session object.
Thanks.
Most people do Session-Per-Request for the reasons you outline and for simplicity.
However, you can open and commit transactions for each "unit of work". So you will have many transactions for each session. (It is also usual practice to make sure that when the transaction is committed, the session is flushed at the same time).
For example, after clicking the save button, open and commit a transaction.
The session will take care of keeping track of all your entities. The transaction will take care of flushing to the database when necessary.
With this setup it should be easier to debug your problem.
For the ASP.NET project I'm working on now, I use a combination of these approaches.
I open an ISession at the beginning of a request and close it at the end of the request, as you do with your first approach, and I use the session to load any entities that need to remain attached to a session for the duration of the request.
However, when I need to save or update or delete an entity, I create a new transient object and hand it to a new ISession, separate from the one tied to the request. For additional units of work, I create additional sessions.
You may find NHibernate Burrow helpful, or at least interesting in this regard, as it is designed to assist with session management in ASP .NET applications, implementing the concept of a "long-running conversation" that spans multiple requests.
I think your real question is why cant I get my objects to save.
Even thought you are using a single ISession you still need to either Flush the session or commit transaction for some Save/Update/Delete actions to be commited.

Categories

Resources