2010-01-11 58 views
1

我有一个仓库,像这样:事务边界应在哪里存储库模式?

public interface IRepository 
{ 
    void Save<T>(T entity); 
    void Create<T>(T entity); 
    void Update<T>(T entity); 
    void Delete<T>(T entity); 
    IQueryable<T> GetAll<T>(); 
} 

我的问题是,我的事务边界应该在哪里呢?我应该在每种方法上打开一个新的事务并在返回之前提交它?还是应该围绕整个存储库进行交易,以便只在存储库处置/垃圾收集时才提交事务?

回答

1

工作单元肯定是要走的路。如果您将SQL Server与本地数据库一起使用,TransactionScope将为您执行大部分繁重的工作;只要你在仓库之间共享会话(你正在通过构造器注入进行操作,那么......),那么你可以将它们嵌套到你的内心。默认情况下,它会在“环境”事务中使用(如果有的话),如果没有,则会启动一个新的事务,这与您想要的工作单元的行为完全相同。

所以你的仓库可能是这样的:

public class UserRepository : IUserRepository 
{ 
    public UserRepository(ISession session) 
    { 
     this.Session = session; 
    } 

    public void Save(User user) 
    { 
     using (TransactionScope tsc = new TransactionScope()) 
     { 
      Session.Save(user); 
      tsc.Complete(); 
     } 
    } 

    protected ISession Session { get; set; } 
} 

public class OrderRepository : IOrderRepository 
{ 
    public OrderRepository(ISession session) 
    { 
     this.Session = session; 
    } 

    public void Save(Order order) 
    { 
     using (TransactionScope tsc = new TransactionScope()) 
     { 
      Session.Save(order); 
      tsc.Complete(); 
     } 
    } 

    protected ISession Session { get; set; } 
} 

然后你就可以像这样从事的工作完成单位:

User currentUser = GetCurrentUser(); 
using (TransactionScope tsc = new TransactionScope()) 
{ 
    ISession session = SessionFactory.OpenSession(); 

    Order order = new Order(...); 
    order.User = currentUser; 
    IOrderRepository orderRepository = GetOrderRepository(session); 
    orderRepository.Save(order); 

    currentUser.LastOrderDate = DateTime.Now; 
    IUserRepository userRepository = GetUserRepository(session); 
    userRepository.Save(currentUser); 

    tsc.Complete(); 
} 

如果你不喜欢TransactionScope或不允许您从有效使用它,那么你可以始终实现自己的UOW或使用现有的实现。或者,如果你只是一个建筑奇怪的怪物,那么你可以同时使用 - 使用一个通用的工作单元接口与一个主要的DI库,并使用TransactionScope实现具体的UOW。

+0

这是一个工作模式单元的例子吗? – 2010-01-11 23:47:57

+0

'TransactionScope'从根本上说是一个UOW实现,所以是的;如果你想要一个“真正的”UOW,那么你应该使用一个接口来代替工厂或者IoC容器,并且在一个实现中包装'TransactionScope'。但是如果你的目标将永远是SQL Server,那么'TransactionScope'本身通常就够用了。 – Aaronaught 2010-01-12 00:45:34

+0

工作单元看起来像是我所称的服务的同义词,所以我不明白为什么它是过度的,UOW不是。有人可以解释它是如何根本不同的?不要将“服务”与“Web服务”或WSDL混淆。 – duffymo 2010-01-12 01:45:54

3

事务不应该应用于存储库,因为如果多于一个需要参与事务,就没有办法说出来。

有一个单独的服务层,使用存储库和模型对象来满足用例。服务方法知道事务边界需要在哪里。这是他们应该应用的地方。

+0

一个服务层会很好,但对于我设计的应用程序来说,这个服务器过度了。我只想让存储库像内存中的集合一样工作,所以这就是为什么我公开IQueryable的原因。 – 2010-01-11 23:48:47

0

其中一个选项是工作模式的单位。这在之前的几个问题中已经解释过了。