MySQL IF陈述式竞争条件

t1rydlwq  于 2022-10-31  发布在  Mysql
关注(0)|答案(1)|浏览(164)

为了简单起见,假设有两个表AB,它们分别在非键INT列COLUMN_ACOLUMN_B上具有唯一索引。我想执行类似下面的伪SQL的操作。(注意,这 * 应该 * 在存储过程中,但根据https://mariadb.com/kb/en/lock-tables/,这是不允许的。)

IF COLUMN_A != x for all rows of A
   Single query to insert a row into B with COLUMN_B = x (if not exist)

问题是代码的其他部分可能读取AB,但是x在这两个代码中都不存在,并尝试在IF语句和插入查询之间将x插入到A中。争用条件似乎需要在A上设置读/写锁。我认为InnoDB'的内部锁定将防止这种情况发生(即,在执行插入之前,将释放在IF语句期间使用的任何锁定)。
最重要的是,COLUMN_A和COLUMN_B在形式上是不相关的,因此似乎没有一种直接的方法可以在它们之间强制实施唯一性约束(假设涉及A和B的视图可能是不可更新的)。(只要它们位于不同的表中,我就可以在它们之间创建某种“关系”,但我不确定是否有任何方法可以做到这一点。)在这种情况下,有必要对A进行表锁吗?
这样的解决方案似乎更好:Can I use row locks on rows that have not been created yet?但这个问题是关于Postgres的,MySQL中似乎没有这些特性。

  • 谢谢-谢谢
ncecgwcz

ncecgwcz1#

将条件放入INSERT语句中,而不是使用IF语句。

INSERT INTO B (col1, col2, col3, ...)
SELECT val1, val2, val3, ...
FROM DUAL
WHERE NOT EXISTS (
    SELECT *
    FROM A
    WHERE column_a = 'x'
)

相关问题