[疑问] [已解决] updateOrCreate () 这类方法应对并发请求的问题
为了说明场景我们假设一个不太合理的场景 :
要更新某人的个人说明, 由于某种原因 user_id 在 Message 表中并不是unique的, 处理如下
Message::updateOrCreate(['user_id' => $user_id], ['content' => $content, 'age' => $age]);
现在有一个新用户, 他进入到了个人信息页面要补充自己的个人信息, 填写完 content 后点击 submit 发送 'ajax' 请求, 但他1s内点击了多次, 就会导致数据库出现多条同一 user_id 的多条记录.
这显然不是我们想要的结果, 我们预期每个 user_id 只有一条记录.
产生这个问题的原因是在 updateOrCreate() 方法会先根据条件 user_id 进行查询, 而在连续的快速点击发送的 ajax 请求中数据库会在执行
insert into messages .....
操作前执行多条
select * from messages where (user_id = 2) limit 1
查询, 而查询结果都会显示为空(因为 insert 还未被执行), updateOrCreate 判断需要的是都是 create操作而不是 update, 结果数据库就会产生多条同一 'user_id' 同一 'content'的结果.
这种每秒不超过5次的请求都会产生意料之外的结果, 这是否意味着 updateOrCreate 这类由框架封装的查询语句不适合在某些严谨的应用场景下使用?
以上假设已经验证过成立, 可惜不能发动图...没法发上来
也许这个问题有些不合理, 甚至很愚蠢.
如果您能指出或者解答该问题, 这将对我帮助很大!
谢谢!
问题表述不够严谨的: [[[[[@Wi1dcard](https://learnku.com/users/32249)](https://learnku.com/users/32249)](https://learnku.com/users/32249)](https://learnku.com/users/32249)](https://learnku.com/users/32249) 已在评论进行了补充
已解决:
如果把问题扩展到提交的用户不仅是同一个人的情况, 那么问题可以归类为 并发下重复写入 的问题,
而一般的解决方式有以下几种:
- 加
unique索引 - 加
表锁 - 缓存过滤重复提交
更多解决方式可搜索 如何并发下避免重复写入
问题参考
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
推荐文章: