NHibernate with TransactionScope

前端 未结 6 1511
闹比i
闹比i 2020-12-02 18:25

Can anyone give me a quick overview of using TransactionScope with NHibernate? Do I need to do anything special with the session/IEnlistmentNotification/etc. to get this to

相关标签:
6条回答
  • 2020-12-02 19:04

    According to Fabio Maulo in comments related to NH-2107:

    You can use TransactionScope and you should continue using NH's transaction too. Where you have read that the Usage of TransactionScope mean the avoid of usage of NH's transaction ?

    I would have assumed that explicit usage of NHibernate's transactions not necessary, but aparently that's best practice

    0 讨论(0)
  • 2020-12-02 19:08

    Also, if you are using TransactionScope, upgrade to NHibernate 2.1. It is only with 2.1 that NH really gotten good integration with TransactionScope.

    0 讨论(0)
  • 2020-12-02 19:17

    I believe you can replace NHibernate transactions with this as long as you respect some constraints as some have already said:

    • Use a reasonably recent NHibernate version (>=3.1).
    • The underlying ADO.NET data provider must support TransactionScope (ok for SQL-Server, Oracle >= 10 with ODP.NET).
    • Create your NH session within the TransactionScope to ensure it gets enlisted.
    • Handle NHibernate flushing manually. See also here and here.
    • Prepare for distributed transactions. If you create multiple sessions in one scope, the initially local transaction might get promoted to a distributed transaction. I saw this happen even with same connection strings on an Oracle 11.2 DB using ODAC 11.2.0.3.20. On SQL-Server 2008 R2 it did not promote. (BTW, one can see this by watching Transaction.Current.TransactionInformation.DistributedIdentifier which is null for local transactions.) While distributed transactions have some advantages, they are more expensive and it is some extra pain setting them up. (See here how to do this for Oracle). To be sure promotion never happens in Oracle, set "Promotable Transaction=local" in your connection string. This creates an exception if some code tries to do so.

    I hope that's all ;-)

    PS: I added the Oracle details because they where my concern and others might benefit.

    0 讨论(0)
  • 2020-12-02 19:21

    The above works OK provided you are using a connection provider that supports the use of a Light-weight Transaction Manager, such as SQL Server 2005/2008.

    If you are using SQL Server 7/2000 then all of your transactions will become Distributed Transactions even if you only hit one database/resource. This is probably not what you would want in most cases, and will be expensive performance wise.

    So checkout if your connection provider and database server combination are suitable for use with TransactionScope.

    0 讨论(0)
  • 2020-12-02 19:23

    I have been using nHibernate 2.1 for awhile, and after a few production issues and trying quite a few variations, we have settled on the following method, as per Avoiding Leaking Connections With NHibernate And TransactionScope:

            using (var scope = new TransactionScope(TransactionScopeOption.Required))
            {
                using (var session = sessionFactory.OpenSession())
                using (var transaction = session.BeginTransaction())
                {
                    // do what you need to do with the session
                    transaction.Commit();
                }
                scope.Complete();
            }
    

    As we are using MSMQ and WCF so we had to use the ambient transaction.

    We found that not using session.BeginTransaction() caused a connection leak. We also found that re-using a session after committing a transaction caused a race condition (nHibernate is not thread safe and DTSC Commits/Rollbacks occur on a background thread).

    0 讨论(0)
  • 2020-12-02 19:27

    I've testing this out using varying vendors and it just works. If you don't have "scope.Complete()" then the transaction will roll back. You may need to have MSDTC running the machine(s) involved if there is more than one durable resource. In that case MSDTC will automatically detect the ambient ADO.NET transactions and manage the whole thing.

    0 讨论(0)
提交回复
热议问题