簡單
DB::beginTransaction(); // 開啟事務
$good = \App\Models\Good::sharedLock()->first(); //共享鎖 s鎖 讀鎖 (名字真多...)
// $good = \App\Models\Good::lockForUpdate()->first(); //排他鎖 x鎖 寫鎖...
DB::commit();
事務與鎖
用鎖需要先開啟事務, 事務提交,會自動解鎖。
例項說明
超賣
這個程式碼多人訪問肯定會出現超賣的。
(如果這個程式碼用共享鎖 不但不能解決問題,還會造成死鎖)
測試
ab -n 6 -c 3 http://mask.ymindex.test/api/test
(978
出現多次,那麼到0
的時候,也會出現多次,導致超賣)
使用排他鎖解決超賣
共享和排他
共享: 我可以讀
寫
加鎖
,別人可以 讀
加鎖
。
排他: 只有我 才 可以 讀
寫
加鎖
,也就是說,必須要等我提交事務,其他的才可以操作。
行鎖: 鎖只對一行生效,比如 id=1
的那行
表鎖: 鎖對整個表都生效
死鎖: 互相依賴,比如:多個鎖同一行/表資料。
我要修改: 你告訴我你鎖了,等我先修改完。
你要修改: 我也鎖了,等我先修改完。
我要修改: 你告訴我你鎖了,等我先修改完。
...... 一萬後
Laravel事務: DB::transaction(function () {}, 5);
5是死鎖時重複執行的次數
.....
排他問題
會影響訪問,你想,在鎖期間,別人連商品點選來都看不了 (要等釋放鎖)。
所以我選擇redis
的 lpop
。
if(! Redis::LPOP('stock'))
return 庫存不足;
本作品採用《CC 協議》,轉載必須註明作者和本文連結