记录一个问题

在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 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 5
lji123123

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

4年前 评论
AloneUtopia 4年前
normaluser (楼主) 4年前
JerryBool 4年前
yema

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

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

file

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

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

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

4年前 评论
AloneUtopia 4年前
normaluser (楼主) 4年前
JerryBool 4年前

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

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

我刀呢

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

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