[疑问] [已解决] 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 协议》,转载必须注明作者和本文链接
推荐文章: