0

我有一个应用程序,它将有一些表示层(web、移动、wpf、wcf、在后台工作的 Windows 服务等),我们正在使用 NHibernate 来持久化域对象。我们将有存储库(类库)来持久化数据,一个服务层使用这些存储库根据业务规则进行持久化。我的问题是,我们不知道如何在这个服务层实现事务管理。我们可能会在同一个服务层方法中使用(多个)存储库,我们需要控制服务层上的事务。我想实现这样的东西(通过属性):

public class DomainObjectService
{
   [Transactional]
   public bool CreateDomainObject(DomainObject domainObject, /* other parameters */)
   { 
       foreach(var item in /* collection */)
       {
           _itemRepository.Save(item);
       }

       if (/* some condition */) {
          /* change the domainObject here */
       }

       _domainObjectRepository.Save(domainObject);
   } 
}

当我们遇到错误时,这个 Transactional 属性是否通过 Commit/RollBack 控制我的事务。是否可以?还是有另一种解决方案来做到这一点?

谢谢

4

1 回答 1

3

你所问的没有一个直截了当的答案。

您希望拥有的行为听起来像是您需要实现一个工作单元模式。

NHibernate 自己的 ISession 实际上是一个工作单元的实现。我个人建议实现你自己的工作单元,这样你就可以更好地控制你的特定应用程序认为什么是工作单元。

在服务层类中使用属​​性对我个人来说真的没有多大意义。我见过人们在处理事务的 MVC 应用程序中创建自定义控制器属性,但我个人从未同意这种实现方式。

您提到在服务层使用多个存储库。这是一种非常普遍的做法,但这也意味着这些存储库中的每一个都需要在同一个工作单元中运行。如果您的应用程序使用依赖注入,那么一种选择是让每个存储库在其构造函数中接受一个 ISession。您选择的依赖注入框架可以设置为将相同的 ISession 注入所有存储库。您的设置可以配置为在每次创建新 ISession 时开始新事务。

您还提到了不同的表示层,例如 Web、移动、wpf 等。您在每种不同类型的应用程序中处理会话和事务的方式可能完全不同。这就是为什么我总是向人们指出工作单元方向的原因,因为每种不同的应用程序类型对于它所认为的工作单元可能有完全不同的定义。对于 Web 应用程序,您通常会为每个 Web 请求使用一个新的工作单元。对于 wpf 应用程序,工作单元可以是每个屏幕,或者直到用户点击保存按钮等。此外,通过实现一个工作单元,您可以在这些不同的应用程序类型中更轻松地重用相同的工作单元实现.

同样,这不是一个希望直接回答的问题,但总的来说,我通常使用自定义工作单元和依赖注入框架来使这个问题更容易处理。

以下是您可能希望调查的一些有用链接:

于 2012-08-30T15:38:42.293 回答