假设我有两个InnoDB表——TableA
和TableB
。TableB
中有一条记录,而TableA
为空。
我还有两个平行的过程。
CCD_ 5正在CCD_ 6或CCD_。它执行两个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版本。
测试以下各项:
计划A:你建议的工会。
计划B:将SELECTs
封装在事务中,并在每个事务上使用FOR UPDATE
。
计划C:封装一个事务并使用隔离模式SERIALIZABLE
。我更喜欢这个,因为它表明你真的不能让两个线程同时接触这些表。
注意:我不知道哪一个会/不会起作用。