【发布时间】:2020-04-20 07:57:59
【问题描述】:
由于一些高可用性考虑,我设计了一个系统,其中多个进程将通过数据库进行通信/同步(最有可能是 MariaDB,但我愿意研究 PostgreSQL 和 MySQL 选项)。
已确定的要求之一是进程必须从数据库中获取一项工作,而不能让另一个进程同时获取相同的工作。
具体来说,这是我想到的竞争条件:
- 进程 A 启动 SQL 事务并运行
SELECT * FROM requests WHERE ReservedTS IS NULL ORDER BY CreatedTS LIMIT 100。这里ReservedTS和CreatedTS是DATETIME列,用于存储工作提交进程创建工作片段的时间,并相应地保留工作执行进程。 - 进程 B 启动事务,运行相同的查询并获得相同的结果集。
- 进程 A 运行
UPDATE requests WHERE id IN (<list of IDs selected above>) AND ReservedTS IS NULL SET ReservedTS=NOW() - 进程 B 运行相同的查询,但是,由于其事务有自己的数据快照,
ReservedTS对进程 B 将不为空,因此项目被保留两次。 - 进程 A 提交事务。
- 进程 B 提交事务,覆盖进程 A 的值。
您能帮忙解决上述数据竞争吗?
【问题讨论】:
-
我预计 6) 会失败。
-
@jarlh,为什么?这是在某处指定的吗?我想阅读更多内容。
标签: sql database concurrency mariadb race-condition