如何在 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 协议》,转载必须注明作者和本文链接
专心学习不瞎搞
本帖由系统于 2年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 16

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

3年前 评论
lyxxxh (楼主) 3年前
chentao2019 3年前
chentao2019 3年前
mengdodo

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

3年前 评论

知道乐观锁吗

3年前 评论

我写在事务里sleep(20) ,然后再在另外一个请求里 可读可写,这个加锁感觉没有生效,。,。,。

3年前 评论
L学习不停 3年前
kangfq 3年前
巴啦啦小仙女 (作者) 3年前
zero风来 3年前
巴啦啦小仙女 (作者) 3年前

@wenyu 乐观锁 悲观锁 不是对应的 共享锁和排它锁吗?还是说是新的锁?

3年前 评论
wenyu 3年前

lpop解决超卖是商品上架的时候设置100库存,就往该商品库存队列里塞100个元素吗?

3年前 评论

我使用事务,前端不知道是不是没用帷幕点太快,自增 ID 冲突了,速来参考。

10个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
87
粉丝
105
喜欢
480
收藏
717
排名:109
访问:8.7 万
私信
所有博文
社区赞助商