我正在C#中编写一个呼叫中心程序,其中多个代理从表中逐个加载客户。为了防止多个代理加载同一个客户,我在表中添加了一个新字段以显示该行已被锁定。当我选择一行时,我会更新该行并将锁定字段设置为已选择该行的代理的ID。但问题是在我选择行并且锁定它的时候,另一个代理可以选择同一行,因为它还没有被锁定!有没有办法处理这种情况?数据库是MySQL 5 / InnoDB
答案 0 :(得分:1)
假设您每个代理只能锁定1个配置文件:
--Check for no lock
UPDATE T SET LockField = 'abc' WHERE ProfileId = 1 AND LockField IS NULL;
--Check to see if we updated anything.
--If not, we can't show this row because someone else has it locked
SELECT ROW_COUNT();
在我执行更新之前,我必须选择id ...
如果您在1语句中执行UPDATE,则不会。我们对MySQL语法的了解有点过了 - 但是有点像:
--Check for no lock
UPDATE T SET LockField = 'abc' WHERE ProfileId = (
SELECT ProfileId FROM T WHERE LockField IS NULL LIMIT 1
);
--Check to see what we updated
SELECT * FROM T WHERE LockField = 'abc';
非常容易。
如果你想要更复杂一些(或者MySQL不支持子查询),可以使用带有SELECT的更新锁... FOR UPDATE:
START TRANSACTION;
--Put an update lock on the row till the xaction ends
--any other SELECT wanting an update lock will block until we're out of the xaction
SELECT @id = ID FROM T WHERE LockField IS NULL LIMIT 1 FOR UPDATE;
UPDATE T SET LockField = 'abc' WHERE ID = @id;
COMMIT TRANSACTION;
答案 1 :(得分:0)
结帐LOCK TABLES
和UNLOCK TABLES
:
http://dev.mysql.com/doc/refman/5.6/en/lock-tables.html
您可以将此与Mark的答案结合使用。
答案 2 :(得分:0)