Hel*_*Sam 4 mysql innodb foreign-keys rowlocking
让我用一个 SQL 示例来开始我的问题。
这是表设置:
x和y. 与y.x指x.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;
Run Code Online (Sandbox Code Playgroud)
现在启动一个事务 (Trx A) 来更新 中的行x。
START TRANSACTION;
UPDATE x SET value=value+1 WHERE id = 1;
Run Code Online (Sandbox Code Playgroud)
在提交之前,我将启动另一个事务 (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.
Run Code Online (Sandbox Code Playgroud)
问题是 - Trx B 届时是否会被绞死?为什么以及有什么方法可以解决这个问题?
这已经在 MySQL 5.7.21、Percona 5.7.21、MariaDB 10.2.14 上进行了测试
是的,这是预期的。
Trx A 在记录上有独占锁 (X),因为它正在更新记录。
Trx B 必须获取所有外键引用的共享模式 (S) 锁,以确保满足约束。它等待 Trx A 释放其 X 锁。
没有办法避免这种情况并保持引用完整性。如果您设法禁用锁定,MySQL 将无法保证引用的行存在。
通常的解决方法是删除外键。
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           3170 次  |  
        
|   最近记录:  |