记录一个问题

在ab测试工具 访问量100 并发 100 的情况下出现的问题

原本的like值为

记录一个问题

使用

    DB::table('articles')->where('id' , $request->id)->increment('like');

记录一个问题

记录一个问题

而使用

    return DB::transaction(function() use ($request){
       $article = Article::find($request->id);
       $article->like += 1;
       $article->save();
       return $this->message('点赞成功!');
    });

记录一个问题
记录一个问题

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 5
lji123123

1.increment 方法编译后的结果就是 update like = like +1 where id = 'id',update 语句是行级锁,所有是顺序执行更新的。
2.在事务里面进行查询之后再更新,MySQL 默认使用 RR 级别隔离,所有可能存在并发请求的时候读取的值是同一个,
这里避免的方式是加上 Article::lockForUpdate()->find($request->id); 排它锁,目的是在本次事物执行查询的时候,其他事务是不允许读取的,这样才能防止并发下产生的问题。

1年前 评论
AloneUtopia 1年前
normaluser (楼主) 1年前
di-gua 1年前
yema

那个177, 是 0 - 177, 还是 100 - 177

1年前 评论
normaluser (楼主) 1年前
yema (作者) 1年前
normaluser (楼主) 1年前
yema (作者) 1年前
normaluser (楼主) 1年前

file

这两行代码中间,数据库里面like的值可能被其他请求修改了

1年前 评论
normaluser (楼主) 1年前
lji123123

1.increment 方法编译后的结果就是 update like = like +1 where id = 'id',update 语句是行级锁,所有是顺序执行更新的。
2.在事务里面进行查询之后再更新,MySQL 默认使用 RR 级别隔离,所有可能存在并发请求的时候读取的值是同一个,
这里避免的方式是加上 Article::lockForUpdate()->find($request->id); 排它锁,目的是在本次事物执行查询的时候,其他事务是不允许读取的,这样才能防止并发下产生的问题。

1年前 评论
AloneUtopia 1年前
normaluser (楼主) 1年前
di-gua 1年前

这是个很经典的问题,面试被问到过,实际工作中也遇到过,赞一个

1年前 评论
normaluser (楼主) 1年前

我刀呢

1年前 评论
normaluser (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!