记录一个问题

在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年前
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年前

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