如何在 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 协议》,转载必须注明作者和本文链接
专心学习不瞎搞
本帖由系统于 3年前 自动加精
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 16
mengdodo

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

5年前 评论

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

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

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

5年前 评论
lyxxxh (楼主) 5年前
chentao2019 4年前
chentao2019 4年前

知道乐观锁吗

5年前 评论

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

4年前 评论
wenyu 4年前

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

4年前 评论

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

2年前 评论

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