Multiple write sessions in the same request

Writing to the database from more then one session in the same request it is bad for several reasons. Here is why:

  1. Each session uses a separate database connection. Using more than one session means using more than one database connection per request. This can hurt overall performance, and puts more pressure on the database.
  2. Using different sessions mean that we cannot take advantage of the NHibernate built-in transaction support and have to rely on System.Transactions which is significantly slower.
  3. We can't rely on the database to ensure transactionally safe view of the data, since we are using several different transactions to access the database. Note that this is the case even when using System.Transactions.
  4. When using System.Transactions it forcing you to use DTC in order to keep all sessions in the same transaction. Using DTC leads to bad performance and is more brittle than not using it.
  5. Without using System.Transactions, there is no ability to use a transaction across all the sessions.

For example, let us consider the following code, which is using multiple sessions to perform a single operation:

public void TransferMoney(Account from, Account to, Money amount)
{
    Dao.Withdraw(from, amount);
    Dao.Deposit(to, amount);
}

public void Withdraw(Account account, Money amount)
{
    using(var session = sessionFactory.OpenSession())
    using(var tx = session.BeginTransaction())
    {
        account.MoenyAmount -= amount;
session.Update(account); tx.Commit(); } } public void Deposit(Account account, Money amount) { using(var session = sessionFactory.OpenSession()) using(var tx = session.BeginTransaction()) { account.MoenyAmount += amount; session.Update(account);
tx.Commit(); } }

In this example, we call to the database twice, each time from different session. Because of that, we cannot take advantage of the database native transaction support, since each operation happen in a different transaction. Our choices are to either operate essentially without transactions (in which case, money can literally disappear in the air), or participate in a distributed transaction (System.Transaction).

We are also unable to take advantage of NHibernate's features to increase system performance such as batch multiple statements against the database.

The solution for this is simple: Use just one session per request. The strong recommendation of the NHibernate development team is that you'll always use the ambient / contextual session. NHibernate also provide API that can help you to do so.