mysql数据库出现幻读_[数据库] Mysql如何解决幻读

6325162dd4cc11da288a64789a4cf1a2.png

什么是幻读

一个事务查询2次,得到的记录条数不同。

MVCC 多版本并发控制

undo log

undo log有两个作用:提供回滚和多个行版本控制(MVCC)。

undo log主要存储的也是逻辑日志,比如我们要insert一条数据了,那undo log会记录的一条对应的delete日志。我们要update一条记录时,它会记录一条对应相反的update记录。

insert undo log – 记录insert

update undo log – 记录update和delete,undo 是逻辑记录,记录了每一行修改的值(前后项)。

实现原理

而MVVC则引入了另外一种并发控制,它让读写操作互不阻塞,每一个写操作都会创建一个新版本的数据,读操作会从有限多个版本的数据中挑选一个最合适的结果直接返回,由此解决了事务的竞争条件。

多版本控制的核心是数据快照,而 InnoDB 则是通过 undo log 来存储数据快照。InnoDB 通过 undo log 保存了已更改行的旧版本的信息的快照。

InnoDB 的内部实现中为每一行数据增加了三个隐藏列用于实现 MVCC 。

DB_ROW_ID: 行标识(隐藏单调自增id)

DB_TRX_ID: 插入或更新行的最后一个事务的事务标识符。(删除视为更新,将其标记为已删除)

DB_ROLL_PTR:写入回滚段的撤消日志记录(若行已更新,则撤消日志记录包含在更新行之前重建行内容所需的信息)

根据事物标识符及撤销记录决定读取的快照版本。

如何解决幻读

Mysql的默认隔离级别是Repeatable read(可重复读),这种隔离级别下会产生幻读问题,Mysql通过锁机制及多版本控制解决了幻读现象的发生,主要手段如下:

快照读

事务每次取数据的时候都会取创建版本小于当前事务版本的数据,以及过期版本大于当前版本的快照数据。普通的 select 就是快照读。

当执行select操作是innodb默认会执行快照读,会记录下这次select后的结果,之后select 的时候就会返回这次快照的数据,即使其他事务提交了不会影响当前select的数据,这就实现了可重复读了。

当前读

在 InnoDB 中,默认为 Repeatable 级别,InnoDB 中使用一种被称为 next-key locking 的策略来避免幻读(phantom)现象的产生。

主要采用next-key锁,即行锁和gap锁来控制。

如select * from user where id =1 for update;

如果有id为1的记录则会被加排它(X)锁,如果不存在,则会加上next-key锁,此时插入记录是会排出异常的,以此解决幻读问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值