InnoDB锁策略

所谓的锁策略,就是在锁开销与安全性之间寻求平衡。

 

为了表述简洁,使用了一些缩写,大概标明一下:

  • RC:Read Committed
  • RR:Repeatable Read
  • Mvcc:Multi-Version Concurrency Control
  • RL:Record Lock
  • TL:Table Lock
  • GL:Gap Lock
  • RDBMS:Relational DataBase Management System
  • 2PL:Two-Phase-Locking

 

先贴一张MySQL的架构图,有助于下面的理解:

事务的四种隔离级别不做赘述,今天主要讨论的是RC级别和RR级别;

RC与RR的并发控制均由Mvcc实现,Mvcc是乐观锁中的一种实现方式,所以在这两种隔离级别下读不加锁写加锁,且select模式为snapshot read(与之相对current read);

Mvcc下,start transaction 将带一个version,version递增:

  • 查找:读取记录的版本号等于当前的版本号
  • 增加:插入记录,将创建列的版本号置为当前的版本号
  • 删除:将记录的删除列的版本号置为当前的版本号
  • 更新:insert + delete

细节请查阅相关资料。

 

今天我们做一些小的测试,在测试之前我们需要在脑海中构建一个模型,模型的作用是将复杂的现实世界简单化,然后来解释现实世界,放在这里同样适用,所以我们今天不考虑复杂的情况;

 

我们知道,InnoDB中是支持RL的,而RL锁的是索引列,若无索引,则锁定表内的所有记录(并不是TL,TL在Server实现);

首先创建一张表,然后插入20条记录:

Create Table: CREATE TABLE `tb_zhaojn` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `age` int(10) NOT NULL,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

insert into tb_zhaojn (age,name) values(0,"0");
...
insert into tb_zhaojn (age,name) values(19,"19");

 

下面在RC级别下做测试;

在此之前,需要先设置一下隔离级别,MySQL的默认隔离级别是RR;

另外再开启一个会话窗口,同样地设置,这里就不贴图了;

第一个session做一个update;

第二个session做一个update;

update tb_zhaojn set name = 'b' where age = 2;

结果会如何呢?可能你会觉得,session2将阻塞,因为没有索引,session1在update1时将锁定所有的记录,实际上并不是这样的;

这是为什么呢?我们知道,RDBMS在处理事务时遵循2PL协议,但实际上,MySQL为了提高性能,也会违背此协议;在没有索引时,session1的确在Storage Engine中锁定了所有的记录,然后将结果返回给Server层;Server层过滤,将不符合条件的记录释放锁,从而提高数据库的并发性

 

下面在RR级别下做测试;

首先将两个session的置回RR;

set transaction isolation level repeatable read;

同样地,先在第一个session中执行;

随后在第二个session中执行;

我们发现session2阻塞了,为什么呢?因为RC级别解决的是脏读,不读取到其他事务中未提交的数据即可,所以仅仅由Mvcc即可实现;而RR级别解决的是幻读,仅仅锁定某些符合条件的记录只能保证该记录不被修改,却阻止不了新记录的插入;在RR事务中,解决幻读,直白地说就是阻止某些insert,是由Next-Key实现的(RL + GL),若条件列没有索引,就无法确定匹配范围,将所有记录上锁之后,并在表的头到尾加上Gap锁;

倘若有了索引,那么在索引列上加RL,在索引起始与结束处加GL就可以了,现在来看下面的测试;

session1;

session2;

和我们所预想的一样;

 

欢迎一起讨论!

 

公众号搜索:以镒称铢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值