在 PHP 中,事務(wù)處理是一種確保數(shù)據(jù)庫操作原子性、一致性、隔離性和持久性(ACID)的方法。鎖機(jī)制是事務(wù)處理中的一個(gè)重要組成部分,它可以確保在事務(wù)過程中數(shù)據(jù)不會(huì)被其他事務(wù)修改。以下是幾種常見的鎖機(jī)制及其在 PHP 中的實(shí)現(xiàn):
// 假設(shè)有一個(gè)名為 "users" 的表,其中有一個(gè)名為 "version" 的版本號字段
$selectQuery = "SELECT * FROM users WHERE id = ? FOR UPDATE;";
$stmt = $pdo->prepare($selectQuery);
$stmt->execute([$userId]);
$user = $stmt->fetch();
// 檢查數(shù)據(jù)是否已被修改
if ($user['version'] != $expectedVersion) {
// 數(shù)據(jù)已被修改,放棄當(dāng)前事務(wù)
// ...
} else {
// 更新數(shù)據(jù)
$updateQuery = "UPDATE users SET name = ?, version = version + 1 WHERE id = ? AND version = ?;";
$stmt = $pdo->prepare($updateQuery);
$stmt->execute([$newName, $userId, $expectedVersion]);
// 提交事務(wù)
// ...
}
SELECT ... FOR UPDATE
語句實(shí)現(xiàn)悲觀鎖。// 假設(shè)有一個(gè)名為 "users" 的表,其中有一個(gè)名為 "id" 的字段
$selectQuery = "SELECT * FROM users WHERE id = ? FOR UPDATE;";
$stmt = $pdo->prepare($selectQuery);
$stmt->execute([$userId]);
$user = $stmt->fetch();
// 更新數(shù)據(jù)
$updateQuery = "UPDATE users SET name = ? WHERE id = ?;";
$stmt = $pdo->prepare($updateQuery);
$stmt->execute([$newName, $userId]);
// 提交事務(wù)
// ...
SELECT ... FOR UPDATE
語句隱式地獲取意向鎖。注意:在實(shí)際應(yīng)用中,應(yīng)根據(jù)具體場景和需求選擇合適的鎖機(jī)制。悲觀鎖可能會(huì)導(dǎo)致性能下降,因?yàn)槠渌聞?wù)需要等待鎖釋放。而樂觀鎖可能會(huì)導(dǎo)致事務(wù)重試,因?yàn)閿?shù)據(jù)在事務(wù)過程中可能被其他事務(wù)修改。