[疑問] [已解決] updateOrCreate () 這類方法應對併發請求的問題

Hans941發表於2018-12-06

為了說明場景我們假設一個不太合理的場景 :
要更新某人的個人說明, 由於某種原因 user_idMessage 表中並不是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) 已在評論進行了補充


已解決:
如果把問題擴充套件到提交的使用者不僅是同一個人的情況, 那麼問題可以歸類為 併發下重複寫入 的問題,
而一般的解決方式有以下幾種:

  1. unique 索引
  2. 表鎖
  3. 快取過濾重複提交

更多解決方式可搜尋 如何併發下避免重複寫入
問題參考

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章