2011-03-07 25 views
0

我瞭解交易工作,一切功能如何預期,但我不喜歡我訪問連接提交或者回滾事務的方式。什麼是要訪問一個事務提交或回滾的首選方式?

我有3個服務類可以訪問相同的單身連接對象。我想在一個事務中來包裝這三樣東西,所以我這樣做:

try { 
    $service1 = new ServiceOne; 
    $service2 = new ServiceTwo; 
    $service3 = new ServiceThree; 

    $service1->insertRec1($data); 
    $service2->deleteRec2($data); 
    $service3->updateRec3($data); 

    $service1->getSingletonConnection()->commit(); 
} 
catch(Exception $ex) { 
    $service1->getSingletonConnection()->rollback(); 
} 

通過getSingletonConnection返回的連接對象只是周圍的OCI8連接的包裝,並承諾是oci_commit;回滾是oci_rollback

正如我所說,這是可行的,因爲他們都訪問相同的連接,但通過任意的服務對象訪問連接感覺不對。另外,還有一些在我的應用程序中使用兩個不同的數據庫,所以我需要確保我檢索並提交正確的......不知道是否有周圍,雖然任何方式。

有沒有更好的方式來處理交易?

回答

2

感到不對勁訪問通過任意 服務對象的 連接。

我同意你的100%。

在我看來,如果每個服務只構成數據庫事務的一部分,那麼服務不能直接負責確定要使用的數據庫會話。您應該在定義事務的代碼級別選擇和管理連接。

所以你當前的代碼將被修改爲類似:

try { 
    $conn = getSingletonConnection(); 
    $service1 = new ServiceOne($conn); 
    $service2 = new ServiceTwo($conn); 
    $service3 = new ServiceThree($conn); 

    $service1->insertRec1($data); 
    $service2->deleteRec2($data); 
    $service3->updateRec3($data); 

    $conn->commit(); 
} 
catch(Exception $ex) { 
    $conn->rollback(); 
} 

看起來這將簡化處理你的兩個數據庫的問題,因爲只會有一個地方來決定使用哪種連接,並且您將持有對該連接的直接引用,直到您結束交易。

如果你想從單身連接擴展到連接池,這將是我能想到的唯一方法,以保證所有三個服務調用使用相同的連接。

+0

我完全同意,不過,如果你傳遞的是對象,你甚至可能會考慮完全乾涉「Singleton」實現。 – 2011-03-08 15:04:56

1

單個連接沒有任何內在錯誤。 如果您有多個連接,那麼每個運行獨立的交易。你基本上有兩種選擇。

  • 維護用於每個 三個服務的當前單 連接對象
  • 維護單獨 的連接(與有關開銷) 爲每個服務,並提交/回滾 每個單獨的連接分別 (沒有特別安全,因爲你無法保證ACID一致性 那麼)

作爲一種方式rou第二,你連接到兩個獨立的數據庫實例:使用DB鏈接,這樣你只能連接到一個單一的數據庫

相關問題