為了說明場景我們假設一個不太合理的場景 :
要更新某人的個人說明, 由於某種原因 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 協議》,轉載必須註明作者和本文連結