Laravel 悲觀鎖類型: sharedLock、lockForUpdate

– 適合寫多讀少
– 須使用事務交易。 (注:InnoDB才支援Transaction,MyISAM是不支援的)
– 須以索引欄位進行查詢,以鎖定單行,避免整張表鎖住。
– lockForUpdate 較 sharedLock 嚴格。
– sharedLock:共享鎖。別的事務可以讀,須等待 sharedLock 更新完再寫。
// select … lock in share mode
– lockForUpdate:排他鎖。都不能讀寫,須等待 lockForUpdate 更新完才能讀寫。
// select … for update
– 差異:lockForUpdate,可避免 同時讀到同一初始值,卻在邏輯處理並提交後,後者的操作覆蓋掉前者 的情況。
// 使用事務交易模式
DB::beginTransaction();
try {
// 鎖表
$product = Product::lockForUpdate()->find($id);
// 邏輯處理
if (($product->stock - $buyQty) < 0) {
throw new Exception('庫存不足');
}
$product->decrement('stock', $buyQty);
$product->save();
} catch (\Exception $e) {
DB::rollback();
throw new Exception('無法成立訂單', 500);
}
// 事務提交 - 解除悲觀鎖
DB::commit();
其他延伸閱讀
複習資料庫的-isolation-level-與常見的五個-race-conditions-圖解
