记录一个问题

在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 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 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年前
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年前

file

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

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

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

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

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

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

我刀呢

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

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