为什么插入 table 被锁定?
why is insert on table locked?
我正在尝试 mysql 上的交易级别。
我有会话 S1 和会话 S2。 S1 使用默认隔离级别 Repeatable Read。对于 S2,我设置了隔离级别可序列化。
这里是场景:
S1:
set innodb_lock_wait_timeout = 5;
start transaction;
S2:
set session transaction isolation level serializable;
start transaction;
select count(*) from produkt;
S1:
select count(*) from produkt;
update kategorie set bezeichnung = 'Smartphone' where kategorieid = 1;
S2:
insert into produkt(produktid, bezeichnung, kategorieid_fk) values (201, 'iPhone 8z', 1);
谁能解释一下,为什么来自 S2 的 insert into produkt
现在被阻止了?
这是表架构:
-- Exportiere Datenbank Struktur für transaktiondb
CREATE DATABASE IF NOT EXISTS `transaktiondb`;
USE `transaktiondb`;
-- Exportiere Struktur von Tabelle transaktiondb.kategorie
CREATE TABLE IF NOT EXISTS `kategorie` (
`KategorieID` int(11) NOT NULL AUTO_INCREMENT,
`Bezeichnung` varchar(255) NOT NULL,
PRIMARY KEY (`KategorieID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Exportiere Struktur von Tabelle transaktiondb.produkt
CREATE TABLE IF NOT EXISTS `produkt` (
`ProduktID` int(11) NOT NULL AUTO_INCREMENT,
`Bezeichnung` varchar(255) NOT NULL,
`KategorieID_FK` int(11) NOT NULL,
PRIMARY KEY (`ProduktID`),
KEY `fk_Produkt_Kategorie_idx` (`KategorieID_FK`),
CONSTRAINT `fk_Produkt_Kategorie` FOREIGN KEY (`KategorieID_FK`) REFERENCES `kategorie` (`KategorieID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
您有一个 deadlock MySQL 描述为:
A situation where different transactions are unable to proceed, because each holds a lock that the other needs. Because both transactions are waiting for a resource to become available, neither will ever release the locks it holds.
仔细观察 How to Minimize and Handle Deadlocks 内容:
InnoDB uses automatic row-level locking. You can get deadlocks even in the case of transactions that just insert or delete a single row. That is because these operations are not really “atomic”; they automatically set locks on the (possibly several) index records of the row inserted or deleted.
关于innodb_lock_wait_timeout
的性质文档描述它只适用于禁用inno_db_detect
的场景,这不是默认配置:
The lock wait timeout value does not apply to deadlocks when innodb_deadlock_detect is enabled (the default) because InnoDB detects deadlocks immediately and rolls back one of the deadlocked transactions. When innodb_deadlock_detect is disabled, InnoDB relies on innodb_lock_wait_timeout for transaction rollback when a deadlock occurs. See Section 14.7.5.2, “Deadlock Detection and Rollback”.
此外,作为一般提示,您通常希望使用 start transaction
,然后尽快使用 commit
或 rollback
,并且不要离开会话 "hanging" 以尽量减少这些问题。
我正在尝试 mysql 上的交易级别。
我有会话 S1 和会话 S2。 S1 使用默认隔离级别 Repeatable Read。对于 S2,我设置了隔离级别可序列化。
这里是场景:
S1:
set innodb_lock_wait_timeout = 5;
start transaction;
S2:
set session transaction isolation level serializable;
start transaction;
select count(*) from produkt;
S1:
select count(*) from produkt;
update kategorie set bezeichnung = 'Smartphone' where kategorieid = 1;
S2:
insert into produkt(produktid, bezeichnung, kategorieid_fk) values (201, 'iPhone 8z', 1);
谁能解释一下,为什么来自 S2 的 insert into produkt
现在被阻止了?
这是表架构:
-- Exportiere Datenbank Struktur für transaktiondb
CREATE DATABASE IF NOT EXISTS `transaktiondb`;
USE `transaktiondb`;
-- Exportiere Struktur von Tabelle transaktiondb.kategorie
CREATE TABLE IF NOT EXISTS `kategorie` (
`KategorieID` int(11) NOT NULL AUTO_INCREMENT,
`Bezeichnung` varchar(255) NOT NULL,
PRIMARY KEY (`KategorieID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Exportiere Struktur von Tabelle transaktiondb.produkt
CREATE TABLE IF NOT EXISTS `produkt` (
`ProduktID` int(11) NOT NULL AUTO_INCREMENT,
`Bezeichnung` varchar(255) NOT NULL,
`KategorieID_FK` int(11) NOT NULL,
PRIMARY KEY (`ProduktID`),
KEY `fk_Produkt_Kategorie_idx` (`KategorieID_FK`),
CONSTRAINT `fk_Produkt_Kategorie` FOREIGN KEY (`KategorieID_FK`) REFERENCES `kategorie` (`KategorieID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
您有一个 deadlock MySQL 描述为:
A situation where different transactions are unable to proceed, because each holds a lock that the other needs. Because both transactions are waiting for a resource to become available, neither will ever release the locks it holds.
仔细观察 How to Minimize and Handle Deadlocks 内容:
InnoDB uses automatic row-level locking. You can get deadlocks even in the case of transactions that just insert or delete a single row. That is because these operations are not really “atomic”; they automatically set locks on the (possibly several) index records of the row inserted or deleted.
关于innodb_lock_wait_timeout
的性质文档描述它只适用于禁用inno_db_detect
的场景,这不是默认配置:
The lock wait timeout value does not apply to deadlocks when innodb_deadlock_detect is enabled (the default) because InnoDB detects deadlocks immediately and rolls back one of the deadlocked transactions. When innodb_deadlock_detect is disabled, InnoDB relies on innodb_lock_wait_timeout for transaction rollback when a deadlock occurs. See Section 14.7.5.2, “Deadlock Detection and Rollback”.
此外,作为一般提示,您通常希望使用 start transaction
,然后尽快使用 commit
或 rollback
,并且不要离开会话 "hanging" 以尽量减少这些问题。