RR和RC隔离级别下的锁总结

CREATE TABLE `person` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `test` bigint(20) DEFAULT NULL,
  `tests` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `person_test_IDX` (`test`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8

以下所有不同事务间的sql默认都不作事务提交, gap锁和next key锁不做区分

一 , RC隔离级别

RC 没有gap lock?

事务一:update person set name ='' where test = 25

事务二:

insert into person(test) values(25) 不阻塞

update person set name ='' where test = 25 阻塞

因为RC下,事务一持有test=25索引的record锁, 所以可以执行insert, 而不能执行update(需要查询的那个记录被锁定)

如果RR隔离级别下, 事务二中的两条语句全部阻塞,其中test=25的记录是record锁, (18,+wuqiong)是gap锁

二, RR隔离级别

唯一索引且非范围查询(in查询不算范围查询), 不会产生gap锁

(1)for update/lock in share mode的读, delete, update 

(2)非唯一索引, 唯一索引的范围查询

(1)(2)中任一搭配, 都会产生gap lock,

简单的insert into操作不会产生间隙锁

1. test数据8,10,12, 加锁查询test=10, 锁定范围(8,12)

    test数据8,9,10, 加锁查询test=9, 只有test=9这个行锁,间隙锁是(8,10),等同于不存在

    test数据8, 10, 加锁查询test =10,锁定范围(8, +wuqiong)

    test数据8,10, 加锁查询test=9,锁定范围[8,10) 左闭右开

2. 间隙锁阻塞的是insert操作, 不会阻塞update操作(test 数据有 10,15,20)

事务一: update person set name = '' where test =15

事务二:

insert into person(test) values( 16) 阻塞

update person set name = '' where test = 16  不阻塞

3. 非簇拥索引加锁后,会连带对主键加锁; 

关于连带加锁的问题??????????????

4.record锁和gap锁的区别: 前者阻塞的是insert和update, 后者只阻塞insert,

换言之两个gap锁可以相交, 如test数据13,16,18,25, 以下两个事务不会阻塞

事务一: update person set name = '' where test = 18 , 锁定范围(16,25)

事务二: update person set name = '' where test = 16, 锁定范围(13,18) 

5. 间隙锁的归并

test数据10,13,15,18,20

事务一: select * from person where test=13 for update  锁定(10,15)

事务二: select * from person where test=18 for update  锁定(15,20)

事务三: delete from person where test =15

此时事务一和事务二的锁定范围都变成(10,20)

其他例子可见 https://blog.csdn.net/asdfsadfasdfsa/article/details/81949604 

猜你喜欢

转载自blog.csdn.net/asdfsadfasdfsa/article/details/81974341