实现 NHibernate 嵌套事务行为

发布于 2024-08-29 07:03:15 字数 717 浏览 13 评论 0原文

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

我想要的是打开一笔大交易,然后拆分成小交易。想象一下下面的场景:

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

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

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

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

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

提前谢谢您。

菲利佩

I'm trying to achieve some kind of nested transaction behavior using NHibernate's transaction control and FlushMode options, but things got a little bit confusing after too much reading, so any confirmation about the facts I list below will be very usefull.

What I want is to open one big transaction that splits in little transactions. Imagine the following scenario:

  • TX1 opens a TX and inserts a Person's record;
  • TX2 opens a TX and updates this Person's name to P2;
  • TX2 commits;
  • TX3 opens a TX and updates this Person's name to P3;
  • TX3 rollbacks;
  • TX1 commits;

I'd like to see NH sending the INSERT and the TX2 UPDATE to the database, just ignoring what TX3, as it was rolled back.

I tried to use FlushMode = Never and only flushing the session after the proper Begins/Commits/Rollbacks have been demanded, but NH always update the database with the object's final state, independent of commits and rollbacks. Is that normal? Does NH really ignores transactional control when working with FlushMode = Never?

I've also tried to use FlushMode = Commit and openning the nested transactions, but I discovered that, because ADO.NET, the nested transactions are, actually, always the same transaction.

Note that I'm not trying to achieve a "all or nothing" behavior. I'm looking more to a savepoint way of working. Is there a way to do that (savepoints) with NH?

Thank you in advance.

Filipe

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

醉酒的小男人 2024-09-05 07:03:15

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

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

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

需要强调的是,该 UoW 操作的“事务”并不是直接的 NH (ADO.NET) 事务。我们创建了事务的抽象,因此操作代码会“投票”我们的事务是否可以提交或回滚,但真正的操作只是根据所选的错误策略发生在一切结束时。

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

问候,

菲利普

Just to don't leave this question open forever, I'll post the solution that we've adopted.

We have a unit of work like container that manages the nested transaction behavior. Depending on the kind of treatment that we want, it creates (or not) new sessions. By example:

  • Continue on error: if we want that even if on a transaction error the other ones commits, the UoW container uses different sessions for each "transaction" and flushes every tx in the end of its work;
  • Rollback on error: if we want that on a session rollback (because of an error or a business rollback) every other transaction gets rolled back, the UoW container uses the same session for all of the nested transactions and rolls back everybody in the end.

It's important to say that the "transaction" that this UoW manipulates isn't the NH (ADO.NET) transaction directly. We've created an abstraction of a transaction so the manipulation code "votes" if our transaction might be commited or rolled back, but the real action just occurs in the end of everything, based on the selected error strategy.

We know that this usage isn't very common and only fits on specific scenarios (in our case it's an integration scenario with batch processing), so I'll now post code. If anyone thinks that this implementation can help, please, send me a message and I'll be glad to share the code.

Regards,

Filipe

绝影如岚 2024-09-05 07:03:15

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

NHibernate does not support nested transactions. Each ISession can have at most one active transaction. I'm not sure what you;re trying to accomplish because your example scenario doesn't make sense to me. Committing transaction 1 after the insert would have the same effect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文