我正在使用mariadb。有一個resource
表,其中列id
,used
標誌和其他資源描述符。每行表示一個資源分配單位。我在分配一行時遇到了麻煩。使用SQL分配資源(行)
在每一筆交易,我想:
- 選擇並鎖定行,是不是
used
。 - 將
used
設置爲true
。 - 根據所選行操縱數據庫。
- 然後提交。
要求:
- 可以有很多併發事務。
- 它可以選擇任何不是
used
的行。 - 它不應該阻止。
- 如果步驟3失敗,事務將回滾並重新啓動。最好選擇不同的行。
首先我試過SELECT * FROM resource WHERE used=0 LIMIT 1 FOR UPDATE
,但在同時發生的情況下,第二個事務會阻塞,直到第一個事務結束。
START TRANSACTION
SELECT * FROM resource WHERE used=0 LIMIT 1 FOR UPDATE <-- second tx waits here until first commits
...
COMMIT
然後我嘗試通過ORDER BY rand()
添加隨機性。但似乎這將首先排序整個表,所以仍然阻塞。
START TRANSACTION
SELECT * FROM resource WHERE used=0 ORDER BY rand() LIMIT 1 FOR UPDATE <-- still blocks
...
COMMIT
任何提示?
只是檢查,你使用什麼表格類型 – RiggsFolly
@RiggsFolly我使用InnoDB – Xiao
好吧,現在向我們展示一些你已經嘗試過的代碼。這將有助於解釋你正在嘗試做什麼 – RiggsFolly