2010-01-11 35 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

其中一個選項是工作模式的單位。這在之前的幾個問題中已經解釋過了。