有人能给我一个使用TransactionScope和NHibernate的快速概述吗?我是否需要对session / IEnlistmentNotification / etc执行任何特殊操作。让这个工作?有什么陷阱我应该担心吗?例如,我可以替换所有的hibernate事务:
var transaction = session.BeginTransaction();
try
{
// code
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
}
用这个?:
using (var scope = new TransactionScope())
{
// code
scope.Complete();
}
答案 0 :(得分:18)
我已经使用nHibernate 2.1一段时间了,经过一些生产问题并尝试了很多变化之后,我们根据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();
}
由于我们正在使用MSMQ和WCF,因此我们不得不使用环境事务。
我们发现不使用session.BeginTransaction()导致连接泄漏。 我们还发现在提交事务后重新使用会话会导致竞争条件(nHibernate不是线程安全的,DTSC提交/回滚发生在后台线程上)。
答案 1 :(得分:7)
我使用不同的供应商测试了它,它只是有效。如果您没有“scope.Complete()”,则事务将回滚。如果有多个持久资源,您可能需要让MSDTC运行所涉及的机器。在这种情况下,MSDTC将自动检测环境ADO.NET事务并管理整个事务。
答案 2 :(得分:6)
如果您使用的是支持使用轻量级事务管理器的连接提供程序,例如SQL Server 2005/2008,则上述工作正常。
如果您使用的是SQL Server 7/2000,那么即使您只使用一个数据库/资源,您的所有事务也将成为分布式事务。在大多数情况下,这可能不是您想要的,并且性能代价高昂。
请检查您的连接提供程序和数据库服务器组合是否适合与TransactionScope一起使用。
答案 3 :(得分:4)
我相信你可以用这个替换NHibernate事务,只要你尊重一些约束,就像有人已经说过的那样:
我希望这就是全部; - )
PS:我添加了Oracle详细信息,因为他们关心我和其他人可能会受益。
答案 4 :(得分:1)
此外,如果您使用的是TransactionScope,请升级到NHibernate 2.1。只有2.1才能使NH真正与TransactionScope实现良好的集成。
答案 5 :(得分:1)
Fabio Maulo在与NH-2107相关的评论中表示:
您可以使用TransactionScope,您也应该继续使用NH的交易。 你在哪里读到TransactionScope的用法意味着避免使用NH的交易?
我会假设明确使用NHibernate的交易没有必要,但显然这是最好的做法