如何在 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年前 自动加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 16
mengdodo

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

3年前 评论

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

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

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

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

知道乐观锁吗

3年前 评论

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

3年前 评论
wenyu 3年前

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

2年前 评论

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

9个月前 评论

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