mysql:insert被外键引用行的更新阻止

xqkwcwgp  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(347)

让我从一个sql示例开始提问。
以下是表格设置:
创建表 x 以及 y . 与 y.xx.id .
在中插入一行 x (id=1)。

START TRANSACTION;
CREATE TABLE `x` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `value` INT(11) NOT NULL,
    PRIMARY KEY (`id`)
)  ENGINE=INNODB;
CREATE TABLE `y` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `x_id` INT(11) NOT NULL,
    `value` INT(11) NOT NULL,
    PRIMARY KEY (`id`),
    CONSTRAINT `fk_x` FOREIGN KEY (`x_id`)
        REFERENCES `x` (`id`)
)  ENGINE=INNODB;

INSERT INTO x values (1,123456);
COMMIT;

现在启动一个事务(trxa)来更新 x .

START TRANSACTION;
UPDATE x SET value=value+1 WHERE id = 1;

在提交之前,我正在启动另一个事务(trx b)以向其插入一行 y .

START TRANSACTION;
INSERT INTO y VALUES (null,1,123456);
---- HANGED ----
-- Until Trx A is committed or rolled-back, the Trx B is hanged here.

问题是-预计trx b会在那时被绞死吗?为什么?有什么办法可以解决这个问题?
这已经在mysql 5.7.21、percona 5.7.21、mariadb 10.2.14上进行了测试

vzgqcmou

vzgqcmou1#

是的,这是预期的。
trxa在记录上有一个独占锁(x),因为它正在更新它。
trx b必须在所有外键引用上获取共享模式锁,以确保满足约束。它等待trxa释放它的x锁。
无法避免这种情况并保持引用的完整性。如果您设法禁用锁定,mysql将无法保证引用的行存在。
通常的解决方法是删除外键。

相关问题