==============================================================================
按照非索引列更新
在可重复读的事务隔离级别下,在非索引列上进行更新和删除会对所有数据行进行加锁,阻止其他会话对边进行任何数据的增删改操作。 如果更新或删除条件为c3=4且c3列上没有索引则: 1、不允许其他会话插入任意记录,因为所有记录的主键索引上存在X排他锁,无法申请插入意向X锁(lock_mode X insert intention waiting Record lock) 2、不允许其他会话删除任意记录,因为所有记录的主键索引上存在X排他锁 3、不允许其他会话更新任意记录。因为所有记录的主键索引上存在X排他锁
##=========================================## 测试数据: CREATE TABLE `tb4001` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `c1` int(11) DEFAULT NULL, `c2` varchar(200) DEFAULT NULL, `c3` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_c1` (`c1`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; insert into tb4001(c1,c2,c3) values(2,2,2); insert into tb4001(c1,c2,c3) values(4,4,4); insert into tb4001(c1,c2,c3) values(7,7,7); insert into tb4001(c1,c2,c3) values(8,8,8); ##=========================================## ##测试1:在没有索引的列上更新 ##事务隔离级别:RR 会话1: SET SESSION tx_isolation='REPEATABLE-READ'; START TRANSACTION; SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation; update tb4001 set c2=777 where c3=7; ##=========================================## 会话2: SET SESSION tx_isolation='REPEATABLE-READ'; START TRANSACTION; SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation; insert into tb4001(c1,c2,c3) values(9,9,9); ##执行结果:会话2被阻塞 使用SHOW ENGINE INNODB STATUS \G查看阻塞发生时的锁信息 ------- TRX HAS BEEN WAITING 13 SEC FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 75 page no 3 n bits 80 index PRIMARY of table `test1`.`tb4001` trx id 10573 lock_mode X insert intention waiting Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; ------------------ ---TRANSACTION 10571, ACTIVE 404 sec 2 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 1 MySQL thread id 52, OS thread handle 140674621650688, query id 1201 127.0.0.1 admin ##=========================================## 会话2: SET SESSION tx_isolation='REPEATABLE-READ'; START TRANSACTION; SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation; update tb4001 set c2=888 where c3=8; ##执行结果:会话2被阻塞 使用SHOW ENGINE INNODB STATUS \G查看阻塞发生时的锁信息 ------- TRX HAS BEEN WAITING 5 SEC FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 75 page no 3 n bits 80 index PRIMARY of table `test1`.`tb4001` trx id 10573 lock_mode X waiting Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 0 0: len 8; hex 8000000000000001; asc ;; 1: len 6; hex 00000000293c; asc )<;; 2: len 7; hex b90000001c0110; asc ;; 3: len 4; hex 80000002; asc ;; 4: len 1; hex 32; asc 2;; 5: len 4; hex 80000002; asc ;; ------------------ ---TRANSACTION 10571, ACTIVE 681 sec 2 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 1 MySQL thread id 52, OS thread handle 140674621650688, query id 1201 127.0.0.1 admin ##=========================================## 会话2: SET SESSION tx_isolation='REPEATABLE-READ'; START TRANSACTION; SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation; delete from tb4001 where c3=8; ##执行结果:会话2被阻塞 使用SHOW ENGINE INNODB STATUS \G查看阻塞发生时的锁信息 ------- TRX HAS BEEN WAITING 4 SEC FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 75 page no 3 n bits 80 index PRIMARY of table `test1`.`tb4001` trx id 10573 lock_mode X waiting Record lock, heap no 2 PHYSICAL RECORD: n_fields 6; compact format; info bits 0 0: len 8; hex 8000000000000001; asc ;; 1: len 6; hex 00000000293c; asc )<;; 2: len 7; hex b90000001c0110; asc ;; 3: len 4; hex 80000002; asc ;; 4: len 1; hex 32; asc 2;; 5: len 4; hex 80000002; asc ;; ------------------ ---TRANSACTION 10571, ACTIVE 790 sec 2 lock struct(s), heap size 1136, 5 row lock(s), undo log entries 1 MySQL thread id 52, OS thread handle 140674621650688, query id 1201 127.0.0.1 admin