具有未通信的第一个事务的TransactionScope在分布式事务上失败

时间:2012-11-15 19:09:21

标签: c# nhibernate ado.net transactions transactionscope

尝试调试时,我发现有效执行以下操作的代码:

  1. 创建TransactionScope
  2. 创建一个事务(在这种情况下是一个nHibernate tx,但不是很重要)
  3. 创建第二个事务(在本例中为标准ADO.Net Tx)
  4. 提交第二笔交易
  5. 在交易范围内调用Complete()
  6. 处理交易范围。
  7. 现在 - 无论如何,创建一个事务而不是提交可能是一个坏主意 - 特别是当有(并且那是错误修复)时。

    然而,当测试这个 - 我尝试了上述的各种组合(提交所有交易,一些交易,没有交易(即只有TScope)提交第一个,但不是第二个,添加其他交易等)并且在所有的事情中我发现以下是真实的:

    只有当我未能提交第一个事务且事务范围变得分散时,TScope的Dispose才会失败:

    System.InvalidOperationException:该操作对于登记的当前状态无效。

    我现在很好奇,想知道为什么会这样吗?

1 个答案:

答案 0 :(得分:1)

我怀疑您看到的问题包含其中一个:https://nhibernate.jira.com/issues/?jql=project%20%3D%2010000%20AND%20labels%20%3D%20TransactionScope

我不完全确定会发生什么,但我已经看到了类似的行为,例如:如果NH在环境事务中登记,并且事务以后变为分布式,则调用TransactionScope.Complete()可能会挂起20秒然后失败。

即使您没有使用NH交易,NH也会尝试登记在TransactionScope中。在这种情况下,NH将在环境事务处理的Prepare()阶段刷新更改。它将在数据库连接上执行此操作,但这也已在事务中登记并将获得自己的Prepare()调用。不幸的是我还没有找到确切的问题,但我怀疑在某些情况下会在NHibernate的Prepare()之前调用db连接Prepare()。后者将尝试继续使用数据库连接,这似乎会导致某种死锁。

使用NH事务并在完成事务范围之前提交此事务将使NH在基础数据库连接进入准备阶段之前刷新其更改。