使用IRepository的C#Shared Transactions和NHibernate

Dav*_*vid 0 c# nhibernate transactions irepository

我正在考虑使用NHibernate实现IRepository模式,我有一个问题,我无法回答搜索网络.

假设我有3个存储库,PersonRepository,PersonAddressRepository和PersonAccountRepository.现在假设业务逻辑指示存在调用PersonRepository.Deactivate(),PersonAddressRepository.Deactivate()和PersonAccountRepository.Deactivate()的"Deactivate Person"进程.

我希望能够按照......的方式做点什么.

using (ITransaction transaction = session.BeginTransaction()) { 
    session.Update(Person);
    session.Update(PersonAddress);
    session.Update(PersonAccount);
}
Run Code Online (Sandbox Code Playgroud)

因此,如果任何更新失败,整个过程将在数据库中回滚.现在我对NHibernate的理解是,你只能为每个对象创建一个Session,所以...

var cfg = new Configuration();
cfg.Configure();
cfg.AddAssembly(typeof(Person).Assembly);
ISessionFactory sessionFactory = cfg.BuildSessionFactory();
using (ISession session = sessionFactory.OpenSession()) {
    using (ITransaction transaction = session.BeginTransaction()) {
    session.Save(Person);
}
Run Code Online (Sandbox Code Playgroud)

这是对的还是我弄错了?有关NHibernate的多表更新和事务的事务的最佳实践是什么?

提前致谢.

Ste*_*ger 5

您不应该在存储库或其他地方"吼叫"创建事务.事务由应用程序逻辑定义.这是我在事务处理中看到的最常见的错误之一.

我写了一个管理交易的交易服务:

using (TransactionService.CreateTransactionScope())
{
  repositoryA.DoX();
  repositoryB.DoY();
  TransactionService.Commit();
}
Run Code Online (Sandbox Code Playgroud)

存储库通过服务中的开放事务获取会话:

TransactionService.Session.CreateQuery("...");
Run Code Online (Sandbox Code Playgroud)

根据您的环境,您需要使其更复杂一些.例如,会话可能对业务逻辑不可见,应该放在另一个接口等上.