【Laravel】 悲觀鎖:共享鎖sharedlock、排他鎖lockforupdate

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