【发布时间】:2020-10-21 00:03:07
【问题描述】:
假设我有两个 InnoDB 表 - TableA 和 TableB。 TableB 中只有一条记录,TableA 为空。
我也有两个并行的进程。
Process1 在TableA 或TableB 中寻找一行。它执行两条 SQL 语句 - select * from TableA,然后是 select * from TableB。
Process2 想要将记录从TableB 移动到TableA。它启动一个事务,然后执行查询delete from TableB 和insert into TableA。
不幸的是,这里有一个竞争条件。如果Process2 移动而Process1 在两个select 语句之间的某个位置停止,那么Process1 将永远看不到该行。
解决此问题的一种方法是交换select 语句并首先从TableB 中选择。连同事务和至少READ COMMITED 隔离级别,应该足以检测到至少一张表中的记录。
但是我想知道select * from TableA union all select * from TableB 是否也可以解决问题?我认为它会减少所涉及的部分,并使其不太可能因未来的代码更改而中断(无需担心语句顺序)。但它是否消除了竞争条件?
如果重要,请使用最新的 MariaDB 版本。
【问题讨论】:
标签: mysql concurrency transactions mariadb race-condition