session2 | |
mysql> use test;
// 创建测试表test,id为索引。 mysql> create table `test`.`test` ( `id` int NOT NULL , `col` int NOT NULL ) Engine=InnoDB row_format=dynamic;
mysql> alter table `test`.`test` add index `id` ( `id` )
|
mysql> use test; |
mysql> insert into test values(1, 10);
// 该例子中,id并非PK,故重复id的insert也不会导致锁等待。 mysql> insert into test values(2, 10);
mysql> commit; |
mysql> start transaction;
mysql> insert into test values(2, 20);
mysql> commit; |
mysql> start transaction;
mysql> update test set col = 15 where id = 1;
mysql> commit; |
mysql> start transaction;
// session2和session1的update不在同样的行,无需等待。 mysql> update test set col = 15 where id = 1;
// session1的update导致id=1上的行锁定。此处update在同行,故需锁等待。 mysql> update test set col = 15 where id = 1; //…wait session1
// session1事务结束后,session2继续运行。一般此处等待时间超出inoodb锁等待最大时间后,会自动报mysql异常:ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction。
mysql> commit; |
mysql> start transaction;
mysql> update test set col = 18 where col = 15;
mysql> commit; |
mysql> start transaction;
// session1的where用在非索引列上,引发表锁定。而session2的where用在索引列上,如果session2的结果和session1的结果没有交集,则session2成功获得行锁定并执行。如果二者存在交集,则session2必须等待session1释放表锁。 mysql> update test set col = 20 where id = 3;
// 表锁和行锁存在交集时,行锁等待表锁释放后方可获得。 mysql> update test set col = 20 where id = 1; //…wait session1
mysql> commit; |
mysql> start transaction; // delete的情况与update类似。 mysql> commit; |
mysql> start transaction;
mysql> commit; |