4

我只是想知道如何最好地處理跨多個服務層的事務。服務層使用ORM來存儲數據庫並從中檢索。是否應該在各個服務層中瞭解和處理事務?還是應該由另一層來處理?多服務層和數據庫事務

例如:我有兩個用戶和客戶端的服務層。我想:

1)創建並保存新的客戶端
2)創建並保存新的用戶
3)用戶分配給客戶端

所有在一個單一的交易。

一個簡單的例子可能是這樣的:

$userManagementService = new UserManagementService; 
$newUserData = array(...); 
$newUser = $userManagementService->create($newUserData); 

$clientManagementService = new ClientManagementService; 
$newClientData = array(...); 
$newClient = $clientManagementService->create($newClientData); 

$userManagementService->assignUserToClient($newUser, $newClient); 

應該在哪裏事務邏輯去?

回答

2

不要嘗試在服務層或ORM中執行嵌套事務。

事務對於數據庫連接是全局事務。除非您的RDBMS本身支持嵌套事務您的DB API暴露嵌套事務,否則可能會遇到異常。

有關詳細信息,請參閱我的回答How do detect that transaction has already been started?

由於您使用PHP,你的交易的範圍最多爲一個請求。所以你應該使用容器管理的事務,而不是服務層傳輸。也就是說,在處理請求開始時啓動事務,並在完成處理請求時提交(或回滾)。

如果一個需要回滾的異常在嵌套的ORM操作中發生,那麼使用一個Exception將其冒泡,然後讓容器(即PHP動作控制器)處理它。

+0

困擾,有道理。感謝這個鏈接,在那裏有一些很好的解釋。 – 2009-11-05 13:57:28

1

您是否面臨交易的彙總?這個僞代碼是否與我認爲你所說的相符?

try 
    begin application transaction 
    begin ORM transaction 1 
     create new user 
     commit request 
    begin ORM transaction 2 
     create new client 
     commit request 
    begin ORM transaction 3 
     create user client association 
     commit request 
    commit application tx 
catch() 
    abort ORM tx 3 
    abort ORM tx 2 
    abort ORM tx 1 
    abort app tx 

在任何時候,嵌套事務的回滾可能會拋出異常,這些異常將邏輯上回滾在two-phase commit所有嵌套事務。

我可能沒有得到你想要的東西。