从Innodb看幻读

首先上mysql 官方文档对于Phantom的解释
15.7.4 Phantom Rows
The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.
翻译过来就是同一事务内相同select语句返回不同的纪录集.

对于InnoDb引擎,隔离级别默认为RepeatbleRead,在这种情况下,因为mvcc(多版本并发控制)机制,在同一事务内,我们执行两次select语句,是不会出现不同的纪录集的,那么我们就可以得出InnoDb在RR级别上解决了幻读问题的结论吗?并没有

幻读的两种解释

  • 对于select返回的结果无法做正确的操作
    相关图片 对于RR隔离级别来说,多次select查询的结果集是一样的,但从另一方面来说,其查询的结果集是不新鲜的,其他事务可能已经修改了纪录集,但在select结果中没有得到反应,在事务接下来的操作中(update, delete, insert)可能会出现异常(冲突),
  • 两次select返回不同的纪录集
    例如在InnoDb readCommited隔离级别来说,同一事务相同select语句是有可能返回不同的结果集的,比较符合上面官方文档的解释

如何避免幻读

在RR隔离级别下,推荐使用select for update 或 select lock in share mode, for update 对检索到的行加排他锁, lock in share mode 对检索到的行加共享锁. 在update较为频繁的情况下,尽量使用for update, 因为lock in share mode导致死锁的几率较大,例如两个事务(事务1, 事务2), 事务1获得s锁,事务2也获得s锁(s锁之间不冲突), 这时事务1执行update语句,会导致事务1 blocking,因为x锁需要等待事务2的s锁释放,紧接着事务2也执行update,两个事务都在等待对方释放s锁,即发生了死锁。而死锁所带来的性能影响是很大的。

转载于:https://juejin.im/post/5c0fc7335188256851642834

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值