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