【发布时间】:2014-12-29 14:25:22
【问题描述】:
我在使用 SELECT ... FOR UPDATE 语句时遇到了 LOCK WAIT TIMEOUT 问题。
我准备了我不明白的场景。你能告诉我为什么前三个块立即执行,而最后一个等待吗?
谢谢。
-- I'm using MariaDb
-- T1 is the mysql terminal window 1
-- T2 is the mysql terminal window 2
CREATE TABLE `test` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL
) COMMENT='' ENGINE='InnoDB' COLLATE 'utf8_bin';
INSERT INTO test SET name='foo';
T2: START TRANSACTION;
T1: START TRANSACTION;
T1: SELECT * FROM test WHERE id IN (1) FOR UPDATE;
T2: INSERT INTO test SET name='foo'; -- executed immediately
T2: START TRANSACTION;
T1: START TRANSACTION;
T1: SELECT * FROM test WHERE id IN (1,2) FOR UPDATE;
T2: INSERT INTO test SET name='foo'; -- executed immediately
T2: START TRANSACTION;
T1: START TRANSACTION;
T1: SELECT * FROM test WHERE id IN (1,2,3) FOR UPDATE;
T2: INSERT INTO test SET name='foo'; -- executed immediately
T2: START TRANSACTION;
T1: START TRANSACTION;
T1: SELECT * FROM test WHERE id IN (1,2,3,4) FOR UPDATE;
T2: INSERT INTO test SET name='foo'; -- waits for T1 to commit
T2: commit;
T1: commit;
【问题讨论】:
-
我不熟悉innodb的事务机制,但ransactions通常以“start transaction”开始,执行一堆SQL语句,然后“commit”。但是,您的代码不遵循这种简单的模式。为什么要“开始交易”两次?
-
那么“T1”和“T2”是什么意思呢?会议??
-
感谢您的回答,但开始事务应该会导致任何未决事务被隐式提交提交。所以我没有写任何提交来使示例尽可能简约。 T1是一个mysql终端窗口,T2是第二个终端窗口。忘记提了,会更新原来的问题,谢谢。
-
我不确定“隐式提交”,但“select .. for update”也需要“启动事务”。
-
您的代码的另一个奇怪之处是操作顺序。虽然你把select放在insert之前,实际上insert必须先执行,因为它有第一个“Start transaction”
标签: mysql transactions locking mariadb