我正在用 C# 编写一个调用中心程序,其中多个代理从表中一一加载客户。为了防止多个代理加载同一客户,我在表中添加了一个新字段以显示该行已锁定。当我选择一行时,我会更新该行并将锁定字段设置为选择该行的代理的 ID。但问题是在我选择该行并锁定它时,另一个代理可以选择同一行,因为它尚未锁定!我有办法处理这种情况吗?数据库为MySQL 5/InnoDB
最佳答案
假设您只能为每个客服人员锁定 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();
Before i execute the update i have to select the 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;
关于c# - 如何防止其他 session 在 UPDATE 发生之前选择一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10509004/