【发布时间】:2012-11-15 19:09:21
【问题描述】:
在尝试调试某些东西时,我发现代码有效地执行了以下操作:
- 创建 TransactionScope
- 创建一个事务(在本例中是一个 nHibernate tx,但不是很重要)
- 创建第二个事务(在本例中为标准 ADO.Net Tx)
- 提交第二个事务
- 在事务范围内调用 Complete()
- 处置事务范围。
现在 - 创建一个事务而不提交可能是个坏主意 - 尤其是当有(这就是错误修复)时。
但是,在测试时 - 我尝试了上述的各种组合(提交所有事务,一些事务,没有事务(即只有 TScope)提交第一个,但不是第二个,添加其他事务等)并且在所有的事情中我发现以下为真:
只有当我未能提交第一个事务并且事务范围变得分布式时,TScope 的 Dispose 才会失败:
System.InvalidOperationException : 该操作对于当前征募状态无效。
我现在很好奇,想知道为什么会这样?
【问题讨论】:
-
我很困惑。 TransactionScope 的目的是拥有单个事务,可以是本地/轻量级事务,也可以是分布式事务。 TransactionScope 中的多个事务不是它的设计目的,并且违背了它的目的,恕我直言,这基本上是让 TransactionScope 在后台处理事务。您是指多个连接吗?
-
好的.. 所以.. 两点进一步上述。上述情况似乎不太正确 - 在 TScope 内创建和未打开的任何 nHibernate 事务都会导致问题。为了澄清混淆:我们目前有一个没有事务范围的 nHibernate 堆栈。我们现在需要连接到另一个数据库。我看到的所有示例似乎都有: 1. 打开 TS 2. 打开 NH Tx 3. perorm NH work 4 Commit nh Tx 5 do other DB wrk 6 complete/dispose TS 你是说如果我们使用 TransacionScope,我们不应该使用nH 交易呢?此外 - 我们需要在 NH trans 中进行其他数据库工作。
-
顺便说一句——TScope 似乎是我们想要的原因,因为我们并不总是需要做“其他数据库工作”——因此 TScope 会将它踢到分布式事务中。也许只使用 TScope(而不使用 NH 事务)是正确的解决方案 - 因为它无论如何都会创建一个事务?
-
为了获得最佳结果,您应该始终使用 NH 事务。如果它发生在 TransactionScope 中,它将自动加入其中。如果没有 NH 事务,您可能会遇到问题,因为 NH 事务比 SQL 中的简单 BEGIN/ROLLBACK/COMMIT 具有更多的职责。
标签: c# nhibernate ado.net transactions transactionscope