要避免臟讀,您可以使用以下兩種方法:
SELECT ... FOR UPDATE
語句:在 MySQL 中,您可以使用 SELECT ... FOR UPDATE
語句來鎖定選定的行,直到當前事務結束。這將確保在事務過程中其他事務無法修改這些行。示例如下:
// 開始事務
$pdo->beginTransaction();
try {
// 選擇要鎖定的行
$stmt = $pdo->prepare("SELECT * FROM your_table WHERE condition FOR UPDATE");
$stmt->execute();
// 獲取查詢結果
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 對數據進行處理(例如更新)
foreach ($rows as $row) {
// 更新行
$updateStmt = $pdo->prepare("UPDATE your_table SET column = :value WHERE id = :id");
$updateStmt->execute([':value' => $newValue, ':id' => $row['id']]);
}
// 提交事務
$pdo->commit();
} catch (Exception $e) {
// 發生錯誤時回滾事務
$pdo->rollBack();
throw $e;
}
PHP 的 PDO 擴展支持四種事務隔離級別,您可以根據需要選擇適當的級別。較低級別的隔離級別可能會導致臟讀,但較高級別可以避免臟讀。以下是四種隔離級別的概述:
要設置隔離級別,請在開始事務之前執行以下代碼:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
// 設置隔離級別
$pdo->setAttribute(PDO::ATTR_TXN_ISOLATION, PDO::ATTR_TXN_SERIALIZABLE);
請注意,較高的隔離級別可能會影響性能。因此,在選擇隔離級別時,請根據您的應用程序需求進行權衡。