我可以使用NHibernate';具有分布式事务的AdoNetTransactionFactory?

我可以使用NHibernate';具有分布式事务的AdoNetTransactionFactory?,nhibernate,distributed-transactions,Nhibernate,Distributed Transactions,我正在处理一个与WCF服务中的NHibernate和分布式事务相关的奇怪问题。有关更多详细信息,请参阅 有一件事似乎可以解决我的问题,那就是使用NHibernate的AdoNetTransactionFactory,而不是AdoNetWithDistributedTransactionsFactory 我相信AdoNetWithDistributedTransactionsFactory参与了使NHibernate的二级缓存机制正常工作,但我们没有使用它。在分布式事务中使用AdoNetTrans

我正在处理一个与WCF服务中的NHibernate和分布式事务相关的奇怪问题。有关更多详细信息,请参阅


有一件事似乎可以解决我的问题,那就是使用NHibernate的AdoNetTransactionFactory,而不是AdoNetWithDistributedTransactionsFactory


我相信AdoNetWithDistributedTransactionsFactory参与了使NHibernate的二级缓存机制正常工作,但我们没有使用它。在分布式事务中使用AdoNetTransactionFactory还存在什么(如果有)问题


谢谢你的时间

我强烈建议升级到nhibernate 3.2(或与之相近的版本)。为什么?自2.1版以来,AdoNetWithDistributedTransactionFactory有了显著的改进(读重写)。事实上,它现在可以正确地处理TransactionScope/ambient事务等。在生产环境中运行2.1时,我们遇到了许多与分布式事务相关的问题。我们几乎不得不自己修复大量的东西并重新编译NHibernate。3.2似乎解决了该主题的许多问题


我附近没有源代码,但如果内存没有问题,AdoNetTransactionFactory不会检查/处理环境事务。因此,当会话中不存在NHibernate引导事务时(通过ISession.BeginTransaction()),您就可以使用NHibernate引导事务了。

我注意到您在其他问题/答案中提到:

SqlConnection class is not thread-safe, and that includes closing the connection 
on a separate thread. Based on this response we have filed a 
bug report for NHibernate.
然而,来自:

创建NHibernate会话时,应遵守以下做法:

  • 不要为每个数据库连接创建多个并发ISession或ITransaction实例

  • 在每个事务中为每个数据库创建多个ISession时,请格外小心。ISession本身跟踪加载对象的更新,因此不同的ISession可能会看到过时的数据

  • 该会话不是线程安全的!不要在两个并发线程中访问同一个ISession。一个会话通常只是一个工作单元

    如果您试图多线程连接NHibernate,那么它可能就行不通了。您是否考虑过其他ORM,例如

    不管您选择什么ORM,数据库连接都不会是线程安全的。这是普遍的


    许多DB驱动程序都不是线程安全的。使用单线程意味着如果有多个线程,它们将共享同一个连接。单线程模式不提供线程安全性。它只允许多个线程轻松共享一个“全局”实例-

    对分布式系统事务使用
    AdoNetTransactionFactory
    ,将导致NHibernate忽略这些事务,这将产生以下后果:

    • ConnectionReleaseMode.将不接受后交易
      。相反,NHibernate将在每条语句之后释放连接,因此将从池中重新获取下一条语句的连接。根据您的数据提供程序,这可能会触发事务升级到分布式
    • FlushMode.Commit将不被接受。将需要显式刷新。(
      Auto
      在仍可能发生查询之前进行刷新。)
    • 需要与当前系统事务隔离的工作仍将包含在其中。(除非连接字符串
      Enlist
      属性为
      false
      ),否则此类工作可能包括id生成器查询,例如检索表hilo生成器的下一个高值。如果事务得到回滚,那么NHibernate可能会使用冲突的ID
    • NHibernate会话将无法正确跟踪它在实体上持有的锁。考虑到自己在事务之外,它会考虑它没有锁定。因此,它可能会尝试(通过示例根据用户代码请求)以低于事务在数据库中已经持有的锁定级别来重新锁定它们。不确定这会导致什么结果。(充其量,忽略,最坏的情况…)
    • 一旦开始修改数据,二级缓存将被禁用。在这种情况下,NHibernate会对缓存项进行排序,并仅在事务完成、更新时重新启用它们。但由于它不会知道交易
    • 一些扩展(可能是enver)可能依赖于NHibernate事务事件,并且不会像预期的那样继续工作

    感谢您的回复。我假设你读了我的另一个问题,我提到我们正在使用NH2.1。实际上,我们确实尝试升级到3.2,但它并没有解决我们的问题。在我们的测试中,我们发现AdoNetTransactionFactory不知道环境事务,但底层SqlConnection仍然参与其中,因此即使我们不使用NH事务,一切都仍然有效。我相信AdoNetWithDistributedTransactionsFactory主要负责确保NH的二级缓存机制正常工作,但我想知道它是否存在任何其他问题。在更多情况下,AdoNetWithDistributedTransactionFactory将自动登记到环境事务中,有时在不使用NHibernate事务的情况下工作。尽管不幸的是,即使在3.3中也存在一些问题,因此仍然建议在TransactionScope之外始终使用NHibernate事务。我担心,由于System.Transactions和System.Data.Travis的限制,当前的方法可能存在一些固有的不可修复的问题,我们一直遵循NH多线程指南。问题出在NH本身——如果分布式事务被DB服务器中止,NH将关闭另一个线程上的连接。
    11.2. Threads and connections