c# - 如何防止其他 session 在 UPDATE 发生之前选择一行

标签 c# mysql innodb

我正在用 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/

相关文章:

mysql - 从大表中删除一列

c# - 调试异步ASP.NET Web API Controller 在“任务”窗口中显示 "No tasks to display"

c# - RabbitMQ:直接回复?

mysql - mysql db 用户的用户权限

mysql - 在一个查询中从不同表获取值

MySQL 启动失败 |如何从Config中删除Db?

c# - LINQ:获取表列名称

c# - MVC 2 和 ASP.NET 4 请求验证异常

mysql - Expressjs - 无法在 session 变量中设置未定义的属性 'userId'

MySQL 全文搜索 - 最小标记大小下的 bool 搜索项意味着没有结果返回