==============================================================================
非索引列更新

在读提交的事务隔离级别下,在非索引列上进行更新和删除会对修改行的主键索引上加行锁。
如果更新或删除条件为c3=4且c3列上没有索引则:
1、阻止其他会话删除表中任意行数据
2、允许其他会话插入任意记录,包括允许插入c3=4的记录
3、阻止其他会话更新c3=4的记录(主键上有X排他锁)
4、允许其他会话更新c3<>4的记录,包括允许将c3<>4的记录更新为c3=4的记录。


在读提交事务隔离级别下进行更新和删除操作,存储引擎层会对扫描到的记录加X排他锁,但MySQL Server层对此进行优化,将不满足条件记录上的锁进行释放。

 

##=========================================##
测试数据:
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:在没有索引的列上更新
##事务隔离级别:RC
会话1:
SET SESSION tx_isolation='READ-COMMITTED';
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c2=777 where c3=7;

##=========================================##
会话2:
SET SESSION tx_isolation='READ-COMMITTED';
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
insert into tb4001(c1,c2,c3) values(9,9,9);

会话2未被阻塞成功执行


##=========================================##
会话2:
SET SESSION tx_isolation='READ-COMMITTED';
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
insert into tb4001(c1,c2,c3) values(9,9,7);

会话2未被阻塞成功执行
##=========================================##
会话2:
SET SESSION tx_isolation='READ-COMMITTED';
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c2=888 where c3=8;

会话2未被阻塞成功执行

##=========================================##
会话2:
SET SESSION tx_isolation='READ-COMMITTED';
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
update tb4001 set c3=7 where c3=8;
会话2未被阻塞成功执行
##=========================================##
会话2:
SET SESSION tx_isolation='READ-COMMITTED';
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 10596 lock_mode X locks rec but not gap waiting
Record lock, heap no 8 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 8; hex 8000000000000003; asc         ;;
 1: len 6; hex 00000000294f; asc     )O;;
 2: len 7; hex 26000000391afe; asc &   9  ;;
 3: len 4; hex 80000007; asc     ;;
 4: len 3; hex 373737; asc 777;;
 5: len 4; hex 80000007; asc     ;;

------------------
---TRANSACTION 10575, ACTIVE 1702 sec
2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 52, OS thread handle 140674621650688, query id 1245 127.0.0.1 admin

##=========================================##
会话2:
SET SESSION tx_isolation='READ-COMMITTED';
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 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 10580 lock_mode X locks rec but not gap waiting
Record lock, heap no 8 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 8; hex 8000000000000003; asc         ;;
 1: len 6; hex 00000000294f; asc     )O;;
 2: len 7; hex 26000000391afe; asc &   9  ;;
 3: len 4; hex 80000007; asc     ;;
 4: len 3; hex 373737; asc 777;;
 5: len 4; hex 80000007; asc     ;;

------------------
---TRANSACTION 10575, ACTIVE 232 sec
2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 52, OS thread handle 140674621650688, query id 1245 127.0.0.1 admin


##=========================================##
会话2:
SET SESSION tx_isolation='READ-COMMITTED';
START TRANSACTION;
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
delete from  tb4001 where c3=2;

##执行结果:会话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 10589 lock_mode X locks rec but not gap waiting
Record lock, heap no 8 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 8; hex 8000000000000003; asc         ;;
 1: len 6; hex 00000000294f; asc     )O;;
 2: len 7; hex 26000000391afe; asc &   9  ;;
 3: len 4; hex 80000007; asc     ;;
 4: len 3; hex 373737; asc 777;;
 5: len 4; hex 80000007; asc     ;;

------------------
---TRANSACTION 10575, ACTIVE 493 sec
2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 52, OS thread handle 140674621650688, query id 1245 127.0.0.1 admin

##=========================================##
View Code

相关文章:

  • 2022-12-23
  • 2021-08-21
  • 2021-08-29
  • 2021-05-16
  • 2021-10-30
  • 2021-10-18
  • 2021-10-19
猜你喜欢
  • 2022-12-23
  • 2021-09-29
  • 2022-12-23
  • 2022-02-09
  • 2021-11-04
  • 2021-11-16
  • 2021-06-24
相关资源
相似解决方案