2015-11-13 27 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 (...); 
相关问题