【发布时间】:2023-04-07 00:35:01
【问题描述】:
我有 MySQL (InnoDB) 表,其列 is_locked 显示记录的当前状态(系统现在是否正在处理它)。
另一方面,我有许多节点执行SELECT * FROM table_name WHERE is_locked = 0,然后处理从该表中获取的行。
在我的代码中我这样做:
- 系统从 DB (
SELECT * FROM table_name WHERE is_locked = 0) 获取行 - 系统通过命令
UPDATE table_name SET is_locked = 1 WHERE id = <id>锁定行
问题:
节点工作速度非常快,所有节点都可能获得相同的行,然后它们中的第一个将更新该行并将is_locked 设置为 1
我发现了 LOCKING 表,但我认为这不是正确的方法。 谁能告诉我,如何处理这种情况?
【问题讨论】:
-
您可以锁定 InnoDB 中的单个行。
-
自己存储锁定是一个根本性的错误想法。如果您编写脚本崩溃并烧毁并锁定该行,会发生什么情况。它将被锁定,您无法知道某个进程是否正在使用它。
-
>自己存储锁定是一个根本有缺陷的想法。如果您编写脚本崩溃并烧毁并锁定该行,会发生什么情况。它将被锁定,您无法知道进程是否正在使用它。 – 你说得对,这就是我在这里问你的原因:)
-
至少 a),限制您的选择和 b) 在您的更新中包含
WHERE is_locked=0 and id = blah,这样只有一次更新尝试会成功。检查返回值,如果更新影响了 0 行,您的节点没有获得该锁/不应该处理。所有这一切最好在一个存储过程中完成,首先更新一行,然后返回它更新的那一行,而不是先选择,稍后更新