实现NHibernate嵌套事务行为 [英] Achieving NHibernate Nested Transactions Behavior

查看:118
本文介绍了实现NHibernate嵌套事务行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我想要的是打开一个大交易,将小交易分成几部分.想象以下情况:

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

我希望看到NH将INSERT和TX2 UPDATE发送到数据库,而忽略了回退时的TX3.

我尝试使用FlushMode = Never,并且仅在需要适当的Begins/Commits/Rollbacks之后才刷新会话,但是NH始终使用对象的最终状态更新数据库,而与提交和回滚无关. 那很正常吗?在使用FlushMode = Never时,NH是否真的忽略事务控制?

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

请注意,我并不是在尝试实现全有或全无"的行为.我正在寻找更多的节省点的工作方式. 有没有办法用NH做到这一点(保存点)?

谢谢.

Filipe

解决方案

只是不要让这个问题永远悬而未决,我将发布我们采用的解决方案.

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

  • 继续执行错误:如果我们希望即使发生交易错误而其他人也提交了,UoW容器对每个交易"使用不同的会话,并在工作结束时刷新每个tx;
  • 发生错误时回滚:如果我们希望通过会话回滚(由于错误或业务回滚)来回滚其他所有事务,则UoW容器对所有嵌套事务使用相同的会话并回滚每个结束.

重要的一点是,此UoW操纵的事务"不是直接进行NH(ADO.NET)事务.我们已经创建了事务的抽象,因此,如果我们的事务可能被提交或回滚,则操作代码投票",但实际的操作只是根据所选的错误策略而发生在所有操作的末尾.

我们知道这种用法不是很常见,仅适用于特定场景(在我们的情况下是具有批处理功能的集成场景),所以现在我将发布代码.如果有人认为此实现可以提供帮助,请给我发送一条消息,我将很乐意分享代码.

此致

Filipe

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

解决方案

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

这篇关于实现NHibernate嵌套事务行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆