实现NHibernate嵌套事务行为

实现NHibernate嵌套事务行为,nhibernate,transactions,nested-transactions,savepoints,Nhibernate,Transactions,Nested Transactions,Savepoints,我试图使用NHibernate的transaction control和FlushMode选项实现某种嵌套的事务行为,但是经过太多的阅读,事情变得有点混乱,因此任何关于我下面列出的事实的确认都将非常有用 我想要的是打开一个大事务,将其拆分为小事务。想象一下以下场景: TX1打开TX并插入个人记录 TX2打开一个TX并将此人的姓名更新为P2 TX2提交 TX3打开一个TX并将此人的姓名更新为P3 TX3回滚 TX1提交 我想看到NH将INSERT和TX2更新发送到数据库,只是在回滚TX3时忽略

我试图使用NHibernate的transaction control和FlushMode选项实现某种嵌套的事务行为,但是经过太多的阅读,事情变得有点混乱,因此任何关于我下面列出的事实的确认都将非常有用

我想要的是打开一个大事务,将其拆分为小事务。想象一下以下场景:

  • TX1打开TX并插入个人记录
  • TX2打开一个TX并将此人的姓名更新为P2
  • TX2提交
  • TX3打开一个TX并将此人的姓名更新为P3
  • TX3回滚
  • TX1提交
我想看到NH将INSERT和TX2更新发送到数据库,只是在回滚TX3时忽略它

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

我还尝试使用FlushMode=Commit并打开嵌套事务,但我发现,由于ADO.NET,嵌套事务实际上总是同一个事务

请注意,我并不是在试图实现“要么全有,要么全无”的行为。我更倾向于一种节省点的工作方式NH有没有办法做到这一点(保存点)?

先谢谢你


Filipe不支持嵌套事务。每个ISession最多可以有一个活动事务。我不知道你在说什么;我们正在努力完成,因为你的示例场景对我来说没有意义。插入后提交事务1也会产生同样的效果。

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

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

  • 错误时继续:如果我们希望,即使在其他人提交事务错误时,UoW容器也会对每个“事务”使用不同的会话,并在其工作结束时刷新每个tx
  • 错误时回滚:如果我们希望在会话回滚(由于错误或业务回滚)时,每隔一个事务回滚一次,UoW容器将对所有嵌套事务使用相同的会话,并最终回滚所有事务
重要的是,UoW操作的“事务”不是NH(ADO.NET)事务。我们已经创建了一个事务的抽象,这样,如果我们的事务可能被提交或回滚,操纵代码就会“投票”,但真正的操作只会发生在一切结束时,基于所选择的错误策略

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

问候,


Filipe

像这样使用嵌套事务的实际优势是什么?Paco的想法是,我们可以拥有与跨区域行为相关联的“容器”。这是我们正在构建的集成框架,我们可以有不同的块,它们的跨区域行为不同:实体A和B一起插入,任何错误都会导致整个回滚,但实体C是同一集成的第三部分,即使出错也必须继续。这个场景有点复杂,但我希望这个描述能让您理解。我希望安瑟斯能证实我的理解,并尝试找出解决这些问题的其他方法。Jamie,但根据业务问题,我可能希望回滚TX 1,我希望的行为是它将回滚所有执行的插入/更新。我在上面对Paco的评论使我对形势有了更广泛的了解。我将设法找到另一种方法来解决这个问题。如果我找到另一种方法,我会发回。也许你可以将每个容器隔离在它自己的工作单元(ISession)中,然后它就可以有自己的事务了。您可以使用Lock或Merge组合ISession来组合事务中的容器。Jamie,这就是我要做的。我没有考虑过合并不同的会话(直到现在才有必要这样做),但它可能适合未来的某些情况。无论如何,我们将在一个工作单元中隔离每个容器,该工作单元最终提供管理所有提交/回滚的嵌套特性。在我们在这里再前进一点后,我将发布最终解决方案。非常感谢。