2011-12-12 72 views
2

如何執行多個查詢,usen commit(),如果出現問題,回滾所有查詢?回滾多個查詢

我注意到,如果我換我的查詢,並與裏面的try/catch承諾,只有不成功的查詢被回滾

try{ 

    $pdo->beginTransaction(); 

    // create 10 tables 
    foreach($queries as $query) 
    $result = $pdo->query($query); 

    $pdo->commit(); 

}catch(PDOException $e){ 

    // here if one of the tables fail to be created, undo all operations 
    $pdo->rollBack(); 

} 

回答

2

MySQL不支持嵌入式事務。

如果您認爲您正在進行部分回滾,那麼您檢查它是錯誤的。特別是,不成功的查詢甚至不會運行,所以沒有任何可以回滾的地方。會發生什麼是您沒有真正進行交易,因爲您忘記了START TRANSACTION聲明或者您的表不是InnoDB。

編輯:我剛剛看到您已更新您的問題。您無法回滾DDL語句,如CREATE TABLE。您只能回滾DML語句(SELECTINSERTUPDATE ...)。這不是MySQL限制,這是我知道的所有DBMS引擎中的標準行爲。

+0

確定那個太爛了:(tx – Alex

1
try{ 

    $pdo->beginTransaction(); 
    foreach($queries as $query) 
    $result = $pdo->query($query); 

    $pdo->commit(); 

}catch(PDOException $e){ 
    $pdo->rollBack(); 
} 
+0

不起作用我有beginTransaction但是我仍然得到了3個表創建,即使在創建第四個 – Alex

+0

時出現錯誤啊,你想要在事務中處理表的創建。MySQL不支持回滾表的創建。 –

+0

這不是原來的代碼,刪除了註釋嗎? –

3

你可能有以下情形:

  • 執行10個SQL語句
  • 回滾5 SQL語句
  • 執行10個SQL語句
  • 回滾12 SQL語句

要脫穎而出的唯一途徑這種性質的東西是使用檢查點。就InnoDB和事務處理而言,他們將被稱爲保存點。

雖然在單個事務中有用於處理整個SQL語句塊的START TRANSACTION,COMMIT和ROLLBACK命令,但您必須在兩組SQL語句之間手動注入保存點。

:如果您運行的交易按以下順序

  • INSERT 10行
  • SAVEPOINT savepoint1
  • UPDATE 3行
  • SAVEPOINT savepoint2
  • DELETE 7行
  • ROLLBACK TO SAVEPOINT savepoint1

的結果是7個刪除和3個更新從InnoDB的重做日誌了,但10周的INSERT仍然在日誌和可用於任何髒讀,直到下列之一:

  • COMMIT;
  • ROLLBACK;
  • RELEASE SAVEPOINT savepoint1
  • 後引入額外的DML SAVEPOINT1

在PHP或PDO中可能沒有這樣的支持機制,但MySQL/InnoDB確實擁有這樣的SQL。

請閱讀MySQL文檔中有關如何運行SAVEPOINT and ROLLBACK TO SAVEPOINT. There is also info on removing savepoints without COMMIT or ROLLBACK going off的這一部分。

我剛剛閱讀Brian Fisher的評論,確實MySQL無法回滾表創建(Oracle可以)。事實上,任何表DDL都會提交任何未提交的數據並啓動新的事務。