簡體   English   中英

PHP中的數據庫事務回滾處理

[英]database transaction rollback processing in PHP

try
{
  $con->beginTransaction();

  $this->doSave($con);

  $con->commit();
}
catch (Exception $e)
{
  $con->rollBack();

  throw $e;
}

上面的代碼是處理交易的非常標准的方法,

但是我的問題是:如果$con->rollBack()也失敗了怎么辦?

可能會導致數據庫鎖定,對嗎?如果是這樣,什么是理想的選擇?

使用事務時,基本思想是在調用commit之前,不會有任何東西真正永久地寫入數據庫。

幾種情況:

  • 如果你 :
    • 開始交易
    • 執行一些查詢
    • 回滾
    • 然后查詢被回滾; 這意味着它們的結果未寫入數據庫。
  • 如果你 :
    • 開始交易
    • 執行一些查詢
    • 斷開連接(如果你的PHP腳本結束這恰好-例如,因為一個致命錯誤或的die
    • 然后,不提交查詢-這意味着它們不會被寫入數據庫; 這意味着就像發生了rollback


簡單地說:從begin transaction ,直到您commit ,所有內容都不會永久寫入數據庫。 如果沒有提交,則不會永久寫入任何內容,並且當您的PHP腳本與數據庫斷開連接時,數據庫會“取消”該PHP腳本未提交的內容。

當然,如果您使用的是PHP以外的其他東西來連接數據庫,則這完全相同-例如,命令行MySQL客戶端。

MySQL通過回滾事務本身來處理錯誤情況。

回滾可能是一個緩慢的操作,可能會隱式發生,而無需用戶明確要求(例如,發生錯誤時)。

MySQL文檔涵蓋了您的“假設情況”

如果禁用了自動提交的會話在沒有顯式提交最終事務的情況下結束,則MySQL將回滾該事務。

進一步:

提交和回滾都將釋放在當前事務期間設置的所有InnoDB鎖。

編輯:我為您的建議情況進行了測試。 在MySQL 5中使用innoDB表。

$db = new DB();
$db->beginTransaction();
$db->exec("INSERT INTO `table` (`val`) VALUES('commit?')");
sleep(30);
$db->commit();

正如我在下面的評論中所描述的那樣。 如果允許完成,則在30秒后將事務提交到表。

如果我在允許腳本完成之前將其殺死,則事務將回滾,並且表將保持干凈狀態-如預期的那樣。

使用事務數據庫引擎,例如InnoDB 如果在寫入過程中查詢失敗,這將保證數據完整性。 MySQL默認使用MyISAM引擎,該引擎速度更快且不具有事務性。 您需要做的就是在創建數據庫時更改存儲引擎。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM