如何在 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 协议》,转载必须注明作者和本文链接
关于 LearnKu
推荐文章: