如何在 Laravel 中使用锁

简单

 DB::beginTransaction(); // 开启事务
 $good = \App\Models\Good::sharedLock()->first(); //共享锁 s锁 读锁 (名字真多...)
// $good = \App\Models\Good::lockForUpdate()->first(); //排他锁 x锁 写锁...
 DB::commit();  

事务与锁

用锁需要先开启事务, 事务提交,会自动解锁。

实例说明

超卖

在Laravel模型使用锁

这个代码多人访问肯定会出现超卖的。

(如果这个代码用共享锁 不但不能解决问题,还会造成死锁)

测试

ab -n 6 -c 3 http://mask.ymindex.test/api/test

在Laravel模型使用锁

(978出现多次,那么到0的时候,也会出现多次,导致超卖)

使用排他锁解决超卖

如何在 Laravel 中使用锁

在Laravel模型使用锁

共享和排他

共享: 我可以 加锁,别人可以 加锁
排他: 只有我 可以 加锁,也就是说,必须要等我提交事务,其他的才可以操作。
行锁: 锁只对一行生效,比如 id=1 的那行
表锁: 锁对整个表都生效


死锁: 互相依赖,比如:多个锁住同一 行/表 数据。

: 两个共享锁
我要修改: 你告诉我你锁了,等我("我"指的是你)先修改完。
你要修改: 我也锁了,等我(指我)先修改完。
我要修改: 你告诉我你锁了,等我(指你)先修改完。
...... 一万年后

Laravel事务解决: DB::transaction(function () {}, 5);
5是死锁时重复执行的次数 (详见文档)
.....


排他问题

会影响访问,你想,在锁期间,别人连商品点击来都看不了 (要等释放锁)。

所以我选择redislpop

if(! Redis::LPOP('stock'))
return 库存不足;
本作品采用《CC 协议》,转载必须注明作者和本文链接

专心学习不瞎搞

lyxxxh
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 3

又听别的大佬说不需要在事务中手动使用事务锁,我自己之前也是这么用的,搞迷糊了,反正没超卖.

2周前 评论
lyxxxh (楼主) 2周前

lockForUpdate()有点意思,不过我一般都是用redis解决并发超卖的问题,事务这个东西目的保证业务数据正确,但是放到并发下,机器cpu会爆炸

1周前 评论

知道乐观锁吗

1周前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!