如何在 Laravel 中使用锁
简单
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 协议》,转载必须注明作者和本文链接
推荐文章: