1

在尝试调试某些东西时,我发现代码有效地执行了以下操作:

  1. 创建事务范围
  2. 创建一个事务(在这种情况下是一个 nHibernate tx,但不是很重要)
  3. 创建第二个事务(在本例中为标准 ADO.Net Tx)
  4. 提交第二个事务
  5. 在事务范围内调用 Complete()
  6. 处理事务范围。

现在 - 创建一个事务而不提交可能是一个坏主意 - 尤其是在拥有(这就是错误修复)时。

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

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

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

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

4

1 回答 1

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() 阶段刷新更改。它将在 db 连接上执行此操作,但这也已加入事务并将获得自己的 Prepare() 调用。不幸的是,我无法找出确切的问题,但我怀疑会发生什么,在某些情况下,数据库连接 Prepare() 将在 NHibernate 的 Prepare() 之前被调用。后者将尝试继续使用数据库连接,这似乎会导致某种死锁。

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

于 2012-11-15T22:54:16.147 回答