mysql锁定读取(用于共享模式下的更新和锁定,而不是我想要的)
我有一张桌子mysql锁定读取(用于共享模式下的更新和锁定,而不是我想要的),mysql,locking,Mysql,Locking,我有一张桌子 tasks id, started_at, ... 1, 2017-01-01 10:00:00 2, 2017-01-01 10:00:00 3, NULL 4, NULL ... SELECT * FROM TASKS WHERE started_at IS NULL LIMIT 10 将上述查询的ID保存到ids变量 UPDATE tasks SET started_at = <<NOW>> WHERE id IN <<ids>
tasks
id, started_at, ...
1, 2017-01-01 10:00:00
2, 2017-01-01 10:00:00
3, NULL
4, NULL
...
SELECT * FROM TASKS WHERE started_at IS NULL LIMIT 10
将上述查询的ID保存到ids变量
UPDATE tasks SET started_at = <<NOW>> WHERE id IN <<ids>>
及
但是,当我从另一个连接进行查询时,即使我还没有完成事务,我仍然得到相同的结果集。我认为
更新
是应该进行锁定的地方,因为在这一点上,您不希望任何其他人查询并返回不完整/不一致的数据。因此,您可以尝试执行更新
,如下所示:
LOCK TABLES tasks WRITE;
UPDATE tasks SET started_at = <<NOW>> WHERE id IN <<ids>>
UNLOCK TABLES;
锁表任务写入;
更新任务集在=中的id处启动
解锁表格;
另一个选项是在事务内部执行更新:
START TRANSACTION;
UPDATE tasks SET started_at = <<NOW>> WHERE id IN <<ids>>
COMMIT;
启动事务;
更新任务集在=中的id处启动
犯罪
在这两种情况下,在
更新完成之前,任何人都不应访问正在更新的记录。我实际上已经希望在选择过程中发生锁定,因为我需要确保另一个选择不会获得相同的ID。@Chris您的要求不清楚。您通常会在更新期间使用锁定,以确保其他会话不会在正在更新的记录中看到不一致的数据。具体来说,您可以使用锁定来确保更新被视为原子更新,或者整个更新已经发生,或者还没有发生。
LOCK TABLES tasks WRITE;
UPDATE tasks SET started_at = <<NOW>> WHERE id IN <<ids>>
UNLOCK TABLES;
START TRANSACTION;
UPDATE tasks SET started_at = <<NOW>> WHERE id IN <<ids>>
COMMIT;