5

我正在尝试使用 NHibernate 的事务控制和 FlushMode 选项来实现某种嵌套事务行为,但是在阅读过多之后事情变得有点混乱,所以任何关于我在下面列出的事实的确认都将非常有用。

我想要的是打开一项拆分为小交易的大交易。想象以下场景:

  • TX1 打开一个 TX 并插入一个 Person 的记录;
  • TX2 打开一个 TX 并将这个人的名字更新为 P2;
  • TX2 提交;
  • TX3 打开一个 TX 并将这个人的名字更新为 P3;
  • TX3 回滚;
  • TX1 提交;

我希望看到 NH 将 INSERT 和 TX2 UPDATE 发送到数据库,只是忽略 TX3,因为它已回滚。

我尝试使用 FlushMode = Never 并且仅在要求正确的开始/提交/回滚后刷新会话,但 NH 始终使用对象的最终状态更新数据库,与提交和回滚无关。这正常吗?当使用 FlushMode = Never 时,NH 是否真的忽略了事务控制?

我也尝试使用 FlushMode = Commit 并打开嵌套事务,但我发现,因为 ADO.NET,嵌套事务实际上总是相同的事务。

请注意,我并不是要实现“全有或全无”的行为。我正在寻找一种保存点的工作方式。有没有办法用 NH 做到这一点(保存点)?

先感谢您。

菲利普

4

2 回答 2

8

为了不让这个问题永远悬而未决,我将发布我们采用的解决方案。

我们有一个像容器一样的工作单元来管理嵌套事务行为。根据我们想要的治疗类型,它会创建(或不创建)新会话。举例:

  • Continue on error:如果我们想要这样,即使其他人提交了事务错误,UoW 容器也会为每个“事务”使用不同的会话,并在其工作结束时刷新每个 tx;
  • 错误回滚:如果我们希望在会话回滚时(由于错误或业务回滚)所有其他事务都回滚,UoW 容器对所有嵌套事务使用相同的会话并最终回滚每个人。

重要的是要说这个 UoW 操作的“事务”不是直接的 NH (ADO.NET) 事务。我们已经创建了事务的抽象,因此如果我们的事务可能被提交或回滚,操作代码会“投票”,但真正的动作只是发生在所有事情的最后,基于所选的错误策略。

我们知道这种用法不是很常见,仅适用于特定场景(在我们的例子中,它是与批处理的集成场景),所以我现在将发布代码。如果有人认为这个实现可以提供帮助,请给我发消息,我很乐意分享代码。

问候,

菲利普

于 2010-04-26T21:09:37.147 回答
1

NHibernate 不支持嵌套事务。每个 ISession 最多可以有一个活动事务。我不确定您正在尝试完成什么,因为您的示例场景对我来说没有意义。在插入之后提交事务 1 将具有相同的效果。

于 2010-04-20T02:33:26.277 回答