我有一个应用程序,它将有一些演示层(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控制我的事务。可能吗?或者还有其他解决办法吗?
谢谢
答案 0 :(得分:3)
你提出的要求没有直截了当的答案。
您希望听到的行为听起来像是需要实现一种工作单元格式。
NHibernate自己的ISession实际上是一个工作单元的实现。我个人建议您实施自己的工作单元,以便更好地控制您的特定应用程序对工作单元的考虑。
在服务层类中使用属性对我个人来说真的没有多大意义。我见过人们在处理事务的MVC应用程序中创建自定义控制器属性,但我从未亲自同意这种实现。
您提到在服务层中使用多个存储库。这是一种非常常见的做法,但它也意味着每个存储库都需要在同一工作单元内运行。如果您的应用程序正在使用依赖项注入,那么一个选项是让每个存储库在其构造函数中接受ISession。您可以设置您选择的依赖注入框架,以便将相同的ISession注入所有存储库。您的设置可以配置为每次创建新的ISession时开始新的事务。
您还提到了不同的表示层,例如web,mobile,wpf等。如何处理每种不同类型的应用程序中的会话和事务可能会有很大不同。这就是为什么我总是将人们指向工作单元的方向,因为这些不同的应用程序类型中的每一个都可以对它所认为的工作单元具有完全不同的定义。对于Web应用程序,通常会为每个Web请求使用新的工作单元。对于wpf应用程序,工作单元可以是每个屏幕,或者直到用户点击保存按钮等。此外,通过实现一个工作单元,您可以在这些不同的应用程序类型中更轻松地重用相同的工作单元实现
同样,这不是一个希望直接回答的问题,但总的来说,我通常会使用自定义工作单元和依赖注入框架来使这个问题更容易处理。
以下是一些您可能希望调查的有用链接: