2011-07-23 133 views
3

我真的不明白如何在DBAL中執行交易Doctrine DBAL Transactions

我有以下腳本正在根據行的id更新列。我放了一個不存在於表中的僞造ID(因此使得更新無法進行),但是儘管它是一個事務,但第一次更新仍被提交。如果其中一個失敗,我希望所有的交易都會失敗。

$conn -> beginTransaction(); 
    try{ 
     $try = $conn->prepare("update table set column = '123' where id = 0"); //column exists 
     $try->execute(); 
     $try = $conn->prepare("update table set column = '123' where id = 1"); //column exists 
     $try->execute(); 
     $try = $conn->prepare("update table set column = '123' where id = 120"); //column does not exists 
     $try->execute(); 

     $try = $conn->commit(); 
    } 
    catch(Exception $e) { 
     $try = $conn->rollback(); 
     throw $e; 
    } 

預期的結果,沒有更新,因爲行使用id = 120不存在 真實結果,所有行除了不存在的行更新。

我提前道歉,但面向對象的編程仍然是我的南極。

回答

3

我知道這個問題已經很老了,所以如果有人遇到類似的問題未來,我會解釋一些事情,因爲這種行爲不是錯誤。

$try = $conn->prepare("update table set column = '123' where id = 120"); //column does not exists 
$try->execute(); 

這裏更新條件引用不存在的列,因此查詢不會失敗,它會更新0(零)行;在Doctrine中,受影響的行數由​​方法返回。

你可以拋出一個懷疑來觸發回滾。

$try = $conn->prepare("update table set column = '123' where id = 120"); //column does not exists 
$affected = $try->execute(); 
if ($affected == 0) { 
    throw new Exception('Update failed'); 
} 
1

只有在引發Exception時,此代碼纔會回滾事務。

更新不成功時,它返回false,而不是異常。

您可以嘗試無例外:

$try = $conn->commit(); 
if (!$try) { 
    $conn->rollback(); 
} 

,或者當結果是false拋出異常。

+2

它看起來像$ try = $ conn-> commit();不會把$試着變成一個布爾...沒有什麼真的似乎發生? – Mallow