MySQL数据库Innodb如何在RR级别下解决幻读?

  • 表象:快照读(非阻塞读) – 伪MVCC
  • 内在:next-key锁(行锁 + gap锁 [间隙锁] )

Innodb在可重复读隔离级别下,基于伪MVCC机制实现的快照读(即非阻塞读)来避免让我们看到幻行。
读取数据时的非阻塞就是MVCC机制,MVCC代表着多版本并发控制,读不加锁,读写不冲突,极大地增大了系统的并发性能。

当前读和快照读
  1. 当前读:上了锁的 增删改查语句,操作数据的最新状态
  2. 快照读:不加锁的非阻塞读(有可能查询到数据的以前版本) – select
RC、RR级别下的Innodb的非阻塞读如何实现?(读不加锁,读写不冲突如何实现?)
  1. 数据行里的DB_TRX_ID、DB_ROLL_PRT、DB_ROW_ID字段

DB_TRX_ID : 跟事务相关的,用来标识最近一次对本行记录做修改的id(即事务id)
DB_ROLL_PRT:回滚指针,写入日志的信息(在日志中记录这修改之前的数据方便回滚)
DB_ROW_ID:行号

2.undo日志

undoLog日志分为两种。
一种是insertUndoLog,此日志表示事务对insert新记录产成时需要的日志记录,主要是发生回滚时需要,事务添加成功提交后即可丢弃。
另一种是updateUndoLog,事务对数据delete或者update时所产生的undolog,不仅在回滚时需要,快照读时也需要,所以不能随便删除。只有当数据库中的快照读不涉及该日志记录,该回滚记录才会被线程删除。

通过日志实现了数据的多个版本,每个版本之间都通过DB_ROLL_PRT进行连接。

3.read view

主要是用来进行可见性判断的,判断最终查询到哪个版本的数据。事务的id都是递增的,通过事务得id去undolog中找到该事务适应的数据版本(可见性算法实现)

RC级别下 read-view 是每次执行select语句时 都会生成一个

RR级别下实现可重复读是因为 read-view 在第一次执行 select 语句时生成一个 在同一个事务中后面的所有 select 语句都复用这一个 read-view
mysql的可重复读实现

在默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务。如果需要在一个事务中包含多条SQL语句,那么需要开启事务和结束事务。
开启事务:start transaction;
结束事务:commit 或 rollback。
在jdbc中处理事务,都是通过Connection完成的!
同一事务中所有的操作,都在使用同一个Connection对象!
Connection的三个方法与事务相关:
1.setAutoCommit(boolean):设置是否为自动提交事务,如果true(默认值就是true)表示自动提交,也就是每条执行的SQL语句都是一个单独的事务,如果设置false,那么就相当于开启了事务了;con.setAutoCommit(false)表示开启事务!!!
2.commit():提交结束事务;con.commit();表示提交事务
3.rollback():回滚结束事务。con.rollback();表示回滚事务
实现同一个事务执行多个SQL语句
Spring的事务管理-简单配置–tx
SpringBoot事务管理

RR级别下如何避免幻读?

快照读并不是避免幻读现象的根本。真正防止幻读的是next-key锁

  • 行锁:是对单个行记录上的锁
  • Gap锁:锁定一个范围,但不包括记录本身,防止同一事务的两次当前读出现幻读。

如果精确查询,条件全部命中,则不会使用Gap锁,只会加记录锁
范围查询以及where条件部分命中或者全部不命中时,则会加Gap锁。

  • Gap锁实质上是防止插入的,如果表中有3,5,7 , 9这么几条数据。如果在进行delete操作id为7的数据时,那么Gap锁就会给(5,7] 和(7,9]这个区间进行上锁,防止数据的插入。

Gap锁会用在唯一索引或者主键的当前读中
Gap锁也会用在非唯一索引或者不走索引的当前读中

  • 如果不走索引Gap锁会锁住整个表 此时Gap锁比表锁更消耗性能,应避免。
  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值