4

我們正在開發具有以下架構的.Net應用程序:表示層(使用MVC模式和ASP.Net MVC 2),服務層,數據訪問層(使用實體框架上的存儲庫模式)。如何管理服務層中的事務?

我們已經決定把事務管理服務層,但我們不知道如何實現它。我們想要在服務層級完全控制交易。也就是說,每當控制器調用服務層中的方法時,它都必須是關於數據庫更新的原子操作。

如果在服務層提供的不同服務之間沒有關係,那麼很簡單:每個方法應該在其執行結束時提交更改(即,在所使用的上下文中調用save方法) 。但有時服務層的服務一起工作。

例如:我們提供了一種具有確認方法的運送服務,該服務接收以下參數:運送ID,指示其是否對應於新客戶或現有客戶的標誌,客戶ID(如果運送確認是針對現有客戶的)和客戶名稱(以防其爲新客戶)。如果該標誌設置爲「新客戶」,則服務層必須(a)創建客戶並(b)確認貨件。對於(a)發貨服務調用客戶服務(已經實施創建新客戶所需的驗證和邏輯並將其存儲在數據庫中)。

誰應該承諾在這種情況下的變化?

  • 如果客戶的服務做到這一點?它不能在創建新客戶之後提交更改,因爲在發貨確認方法中稍後可能會出錯,但在直接調用它的情況下(在其他使用情況下,用於創建客戶端),它必須提交更改。
  • 控制器應該調用服務方法嗎?但是控制者不應該知道任何有關交易的事情,我們已經決定把所有的交易知識都放在服務層。
  • 服務層中的事務管理器?如何設計它?誰稱它?何時?

是否有此,我們應該遵循的設計模式?

回答

5

我有一個提交()對我的服務,如果的UnitOfWork是由服務創造了這個只有承諾,如果在構造函數中通過了提交什麼都不做。

我用於服務第二(內部)構造函數:

public class MyService 
{ 
private IUnitOfWork _uow; 
private bool _uowInternal; 

public MyService() 
{ 
    _uow = new UnitOfWork(); 
    _uowInternal = false; 
} 

internal MyService(IUnitOfWork uow) 
{ 
    _uow = uow; 
    _uowInternal = true; 
} 
public MyServiceCall() 
{ 
    // Create second service, passing in my UnitOfWork: 
    var svc2 = new MySecondService(_uow); 

    // Do your stuff with both services. 
    .... 
    // Commit my UnitOfWork, which will include all changes from svc2: 
    Commit(); 
} 

public void Commit() 
{ 
    if(!_uowInternal) 
     _uow.Commit(); 
} 
} 
+0

感謝約翰!這正是我所尋找的答案。 – mmutilva 2011-02-03 20:14:03

1

與替代EF WCF和L2S類似的架構,我們選擇在主服務接口實現類使用的交易。我們使用TransactionScope來實現這一點:

public void AServiceMethod() { 
    using(TransactionScope ts = new TransactionScope()) { 
     service1.DoSomething(); 
     service2.DoSomething(); 
     ts.Complete(); 
    } 
} 

主要缺點是交易可能會變大。在這種情況下,例如,如果事務塊中的某個服務調用僅需要只讀訪問,則我們將其封裝在嵌套的TransactionScope(TransactionScopeOption.Suppress)塊中,以防止在事務生存期中進一步鎖定行/表。