mysql数据库 隔离级别

本文解析了MySQL InnoDB存储引擎中的Undo+Redo事务机制,快照读与当前读的区别,以及Next-Key Lock如何结合Record Lock和Gap Lock解决幻读问题。

Undo + Redo事务的简化过程

假设有A、B两个数据,值分别为1,2,开始一个事务,事务的操作内容为:把1修改为3,2修改为4,那么实际的记录如下(简化): 

  • .事务开始. 
  • .记录A=1到undo log. 
  • .修改A=3. 
  • .记录A=3到redo log. 
  • .记录B=2到undo log. 
  • .修改B=4. 
  • .记录B=4到redo log. 
  • .将redo log写入磁盘。 
  • .事务提交

 

快照读和当前读

MySQL的InnoDB存储引擎默认事务隔离级别是RR(可重复读), 是通过 "行排他锁+MVCC" 一起实现的,在innodb中的操作可以分为当前读(current read)快照读(snapshot read)

 

快照读

使用 MVCC 读取的是快照中的数据,这样可以减少加锁所带来的开销。简单的select操作(当然不包括 select ... lock in share mode, select ... for update)是快照读。

select * from table ...;

当前读

读取的是最新的数据,需要加锁。以下第一个语句需要加 S 锁,其它都需要加 X 锁。

select * from table where ? lock in share mode; # 加读锁select * from table where ? for update; # 加写锁insert;update;delete

在RR级别下,快照读是通过MVVC(多版本控制)和undo log来实现的,当前读是通过加record lock(记录锁)和gap lock(间隙锁)来实现的。

innodb在快照读的情况下并没有真正的避免幻读, 但是在当前读的情况下避免了不可重复读和幻读。

 

 

Next-Key Lock

Next-Key Lock 是 MySQL 的 InnoDB 存储引擎的一种锁实现。

MVCC 不能解决幻读的问题,Next-Key Lock 就是为了解决这个问题而存在的。在可重复读(REPEATABLE READ)隔离级别下,使用 MVCC + Next-Key Lock 可以解决幻读问题。

InnoDB有三种行锁的算法:Record Lock、Gap Lock和Next-Key Lock,其中Next-Key Lock是前两者的结合。

Record Lock

锁定一个记录上的索引,而不是记录本身。

如果表没有设置索引,InnoDB 会自动在主键上创建隐藏的聚簇索引,因此 Record Lock 依然可以使用。

Gap Locks

锁定索引之间的间隙,但是不包含索引本身。例如当一个事务执行以下语句,其它事务就不能在 t.c 中插入 15。

SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE;

Next-Key Lock

它是 Record Lock 和 Gap Lock 的结合,不仅锁定一个记录上的索引,也锁定索引之间的间隙。例如一个索引包含以下值:10, 11, 13, and 20,那么就需要锁定以下区间:

(negative infinity, 10](10, 11](11, 13](13, 20](20, positive infinity)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值