資料庫事務的話題經常伴隨著縮寫詞 ACID,代表原子性、一致性、隔離性和持久性。簡單來說,事務保證資料庫操作可靠地執行,且不受其他並發連線的影響。
但是,一個問題出現了:多個 PHP 腳本可以同時執行交易而互不干擾嗎?要理解這一點,請考慮以下場景:
假設一個名為「employees」的表具有兩個欄位:「id」和「salary」。兩個腳本 script1.php 和 script2.php 同時執行以下程式碼:
<code class="php">$conn->beginTransaction(); $stmt = $conn->prepare("SELECT * FROM employees WHERE name = ?"); $stmt->execute(['ana']); $row = $stmt->fetch(PDO::FETCH_ASSOC); $salary = $row['salary']; $salary = $salary + 1000; $stmt = $conn->prepare("UPDATE employees SET salary = {$salary} WHERE name = ?"); $stmt->execute(['ana']); $conn->commit();</code>
在這種情況下「ana」的最終工資是多少?
答案取決於為 MySQL InnoDB 表引擎所配置的隔離等級。 InnoDB 支援SQL 標準指定的四個隔離等級:
預設情況下,MySQL 使用「已提交讀取」隔離等級。在此等級中,結果將是 11000。這是因為 script1.php 和 script2.php 在提交之前讀取相同的資料。
如果使用「可序列化」隔離級別,結果將為 12000。這是因為 Serialized 可確保交易依序執行並防止其他交易幹擾鎖定的資料。
在給定的範例中,事件順序為:
透過讀取已提交」隔離,兩個腳本在提交之前都會讀取相同的資料。因此,工資的增加不是孤立的,而是應用了兩次,導致增加了 2000。
透過「Serialized」隔離,第一個交易 (script1.php) 鎖定「ana」的行,當它選擇資料。當 script2.php 嘗試選擇相同的資料時,它將等到第一個事務提交。這樣可以確保資料在讀取時不會被其他事務修改,並且工資的增加只應用一次,結果增加了 1000。
因此,同時事務之間的干擾取決於隔離等級和特定的操作順序。了解不同隔離等級的含義對於確保事務在並發環境中按預期運行至關重要。
以上是MySQL 事務與 PDO 可以並發運作而不會發生幹擾嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!