NHibernate session management?

First, let me give a brief description of the scenario. I am writing a simple game where almost all the work is done on the server side with a thin client for players to access it. The player registers or creates an account and can then interact with the game, moving around the grid. When they enter a cell, they must be informed of other players in that cell, and similarly, other players in this cell will be informed that this player is in it. There are many other interactions and actions that can take place, but you should not dwell on them in detail, since this is simply something more. When a player logs out, then returns or the server returns and returns, the entire state of the game must be preserved, although if the server crashes, it does not matter if I lose 10 minutes of changes.

I decided to use NHibernate and the SQLite database, so I read a lot in NHibernate, following the tutorials and writing some sample applications, and I don’t understand how I should do it!

I have a question: what is the best way to manage my sessions? Just from the small amount that I really understand, all these possibilities are jumping onto me:

  • You have one session that is always open that all clients use
  • Conduct a session for each client that connects and periodically cleans it.
  • Open a session every time I have to use any existing objects and close it as soon as the update, insert, delete or request is complete.
  • You have a session for each client, but keep it disconnected and only reconnect it when I need to use it.
  • Same as above, but keep it connected and only disconnect it after a certain period of inactivity
  • Keep entities aloof and attach them every 10 minutes, say, to commit changes.

What strategy should be used to get decent performance, given that there can be many updates, inserts, deletions and requests per second from maybe hundreds of clients at the same time, and all of them must be consistent with each other?

One more question: how to use transactions effectively? Is it good for each individual change to be in its own transaction, or will it work badly when I have hundreds of clients trying to change cells in the grid? Should I try to figure out how to combine similar updates together and place them in a single transaction, or will it be too complicated? Do I even need transactions for most of this?

+7
c # database session nhibernate transactions
source share
4 answers

I would use a session for each request on the server and one transaction per session. I will not optimize performance before the application becomes mature.

The answer to your decisions:

  • You have one session that is always open to all clients: you will have performance problems because the session is not thread safe and you will have to block all session calls.
  • For each client that connects and periodically cleans it, one session is required. You will have performance problems because all data used by the client will be cached. You will also see issues with obsolete cache data.
  • Open a session every time I have to use any of the saved objects and close it as soon as the update, insert, delete or query is complete: you will not have performance problems. The disadvantage is concurrency or corrupted data problems, because the related sql statements are not executed in a single transaction.
  • You have a session for each client, but disconnect it and only reconnect it when I need to use it: NHibernate already has built-in connection management, and it is already very optimized.
  • Same as above, but keep it connected and only disconnect it after a certain period of inactivity: it will cause problems because the number of sql connections is limited and will also limit the number of users of your application.
  • Keep entities aloof and attach them every 10 minutes, for example, to commit changes: it will cause problems due to outdated data in individual objects. You will have to track the changes yourself, which forces you to get a piece of code that looks like the session itself.

Now it would be useless to go into details, because I just repeat the manuals / textbooks / books. When you use a session for each request, you probably won't have problems in 99% of the application you are describing (and maybe not at all). A session is a lightweight class that is not thread safe to live very short. When you want to know exactly how session / connection / caching / transaction management works, I first recommend reading the manual and then asking more detailed questions about obscure subjects.

+8
source share

Read the ' ISessionFactory ' on this NHibernate documentation page . ISession should be single-threaded (i.e. not thread safe), which probably means you shouldn't share it between users. ISessionFactory must be created once by your application and ISession must be created for each unit of work. Remember that creating an ISession does not necessarily lead to opening a database connection. This depends on how the SessionFactory pooling strategy is configured.

You can also see the Hibernate documentation for the session and transaction .

+1
source share

I would like to keep everything in memory, and either the log changes or takes periodic offline snapshots.

0
source share

Read NHibernate Best Practices with ASP.NET , there are some good tips to get you started. As already mentioned, be very careful with ISession, as it is not thread safe, so just keep that in mind.

If you need something more complex, take a look at the NHibernate.Burrow project. It states that "the real strength that Burrow offers is that a Burrow conversation can span multiple HTTP requests."

0
source share

All Articles