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-圖解