我正在处理与Wiber服务中的NHibernate和分布式事务相关的奇怪问题。有关详细信息,请参阅Deadlocks causing 'Server failed to resume the transaction' with NHibernate and distributed transactions。
似乎解决了我的问题的一件事是使用NHibernate的AdoNetTransactionFactory,而不是AdoNetWithDistributedTransactionsFactory。
我相信AdoNetWithDistributedTransactionsFactory涉及使NHibernate的第二级缓存机制正常工作,但我们没有使用它。使用AdoNetTransactionFactory与分布式事务有什么(如果有)其他问题?
谢谢你的时间!
答案 0 :(得分:1)
我注意到你从其他问题/答案中提到:
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's documentation:
11.2. Threads and connections
创建NHibernate会话时应注意以下做法:
如果您尝试使用NHibernate进行多线程连接,那么它可能无法正常工作。您是否考虑过其他ORM,例如Entity Framework?
无论您选择什么ORM,数据库连接都不是线程安全的。这是普遍的。
“许多数据库驱动程序不是线程安全的。使用单例表示如果你有很多线程,它们将共享相同的连接。单例模式不会给你线程安全。它只允许许多线程轻松共享“全球”实例。“ - https://stackoverflow.com/a/6507820/1026459
答案 1 :(得分:1)
将AdoNetTransactionFactory
与分布式系统事务一起使用将导致NHibernate忽略这些事务,这会产生以下后果:
ConnectionReleaseMode.AfterTransaction
不会受到尊重。相反,NHibernate将在每个语句之后释放连接,因此将从池中重新获取下一个连接的连接。根据您的数据提供商,这可能会触发将事务升级为分布式。FlushMode.Commit
不会受到尊重。而是需要显式刷新。 (Auto
在查询可能仍然发生之前刷新。)Enlist
属性为false
。)此类工作可能包括id生成器查询,例如检索表hilo生成器的下一个高值。如果事务得到滚动支持,那么NHibernate可能会使用冲突的ID。答案 2 :(得分:0)
我强烈建议升级到nhibernate 3.2(或接近它的版本)。为什么?从2.1开始,对AdoNetWithDistributedTransactionFactory进行了重大改进(读取重写)。事实上,它现在正确处理TransactionScopes / ambient-transactions等。当我们在生产中运行2.1时,我们遇到许多与分布式事务相关的问题。我们几乎不得不自己修复大量的东西并重新编译NHibernate。 3.2似乎解决了很多关于这个问题的问题。
我没有靠近我的源,但是,如果内存没有让我失望,AdoNetTransactionFactory不会检查/处理环境事务。因此,当会话中不存在NHibernate引导事务时(通过ISession.BeginTransaction()),您将处理它们。