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