实现 NHibernate 嵌套事务行为
我正在尝试使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了不让这个问题永远悬而未决,我将发布我们采用的解决方案。
我们有一个像容器这样的工作单元来管理嵌套事务行为。根据我们想要的治疗类型,它会创建(或不创建)新的会话。举例来说:
需要强调的是,该 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:
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
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.