在PHP中,使用內置的PDO數據庫抽象層,它的情況並不少見有這樣的代碼:PDO嵌套事務引起PHP掛起
function B()
{
$db = new PDO(...);
$db->beginTransaction();
// do something
$db->commit();
}
function A()
{
$db = new PDO(...);
$db->beginTransaction();
// do something
B();
$db->commit();
}
注意,A和B都獲得自己的數據庫連接,並且都開始交易,並且A呼叫B。結果是,在某些情況下(即,B在做某事,其中取決於A確定了),則該編碼模式將導致死鎖。
例如,假設我們有表格Foo
和Bar
。 Foo
包含引用Bar
的外鍵,並設置爲ON DELETE CASCADE
。假設函數A
更新Foo
以更改該外鍵字段的值,然後函數B
刪除Bar
中的現在未使用的記錄。因爲A
的事務未提交,所以B
中的SQL將等待它,儘管在B
返回之前它將永不會提交。 有沒有辦法解決這個問題,而不將數據庫對象傳遞給每個函數?它看起來像PDO本身應該能夠正確處理這一點,只需跟蹤嵌套事務。
我曾嘗試在評論here,其中PDO是子類做嵌套事務計數的解決方案,但它似乎並沒有實際工作 - 我認爲是因爲A()
和B()
的$db
對象是不一樣的情況下,所以他們不知道彼此,並且在任一情況下計數器的值都是不正確的。
「這並不罕見」?真? –
當然,爲什麼不呢?這似乎是最明顯的實現。例如,[PHP文檔](http://www.php.net/manual/en/pdo.connections.php)似乎就是這樣做的 - 參見「Example#2」。你會建議什麼? – CmdrMoozy