2015-11-13 72 views
0

請考慮存在充滿記錄的存儲表。將有許多併發請求從存儲表中選擇並擁有一些記錄。在沒有碰撞的情況下選擇並更新MySQL中的幾行

我不確定,也不知道如何使用Transcations來結合select和update來完成我沒有任何聯盟的情況。

例如,這是我的表:

+----+------+----------+ 
| id | name | is_taken | 
+----+------+----------+ 
| 1 | a |  1 | 
| 2 | b |  0 | 
| 3 | c |  0 | 
| 4 | aa |  1 | 
| 5 | bb |  0 | 
| 6 | dd |  0 | 
| 7 | e |  0 | 
| 8 | ff |  0 | 
+----+------+----------+ 

-

-- first select them 
SELECT * FROM `STASH` WHERE `is_taken` = 0 LIMIT 2 
-- then update and take them to stop others to taking them 
UPDATE `STASH` SET `is_taken` = 1 WHERE `is_taken` = 0 

回答

1

如果您正在使用該表作爲動作隊列和他們短:

START TRANSACTION; 
SELECT ... FOR UPDATE; 
act on them 
DELETE ...; -- assuming you are finished with them. 
COMMIT; 

並檢查在每個階段的錯誤。如果遇到死鎖或鎖定等待超時,請重新啓動。

如果行動需要很長時間,那麼應該使用不同的技術。

因此,請在

  • 多少行闡述一般(和最大)都在表
  • 有多少行,你想一次挑選
  • 才能「進程」多久一排
  • 是否可以在完成時刪除該行。

不同的技術效果更好,取決於你的答案。

0

您可能需要考慮增加擁有者列,如果它不已經有一個,表。然後,只需運行update語句,設置所有者並確定該行已被佔用。每個邏輯交易您應擁有唯一的所有者。

update stash set owner = some_owner, is_taken = 1 where is_taken = 0 limit 2; 

這種說法應該將預計的併發負載下進行測試,看看它如何執行。

然後選擇這些行

select * from stash where owner = some_owner and is_taken = 1; 

然後當它是時間來釋放,使用IDS從上面選擇

update stash set owner = null, is_taken = 0 where id in (...); 
相關問題