“Mysql如何解决幻读问题”
一个工作了4年小伙伴,去一个美团面试,遇到了这样一个问题。
大家好,我是Mic,一个工作了14年的Java程序员
关于这个问题,面试官想考察什么?我们应该如何回答呢?
问题解析
这个问题至少考察的是3年以上开发经验的同学。
Mysql底层去解决并发事务问题,至少是要有一定的技术积累才能真正理解。
而如果作为一个刚工作没多久的程序员,必须要知道数据库的事务隔离级别的问题。
因为不同的隔离级别对于数据的安全性影响是不同的。
也就是存在脏读、幻读、不可重复读等问题。
所谓幻读,就是一个事务前后两次读取到的数据条数不一致。
在第一个事务里面执行一个范围查询,这个时候满足查询的数据只有一条。
接着第二个事务里面插入一条数据并且提交了,然后在第一个事务里面再次查询的时候发现有两条数据满足条件。
在RR事务隔离级别下,引入了MVCC和LBCC这两种方式来解决幻读问题。
MVCC类似于一种乐观锁的设计,简单来说就是针对每个事务生成一个事务版本,然后针对这个版本定义了访问规则
一个事务只能看到第一次查询之前已经提交的事务以及当前事务的修改。一个事务不能看到当前事务第一次查询之后创建的事务,以及未提交的事务修改。
但是,如果在一个事务里面存在当前读的情况下,MVCC还是会存在幻读问题,因为当前读不是读快照,而是直接读内存。
所以针对这种情况,可以使用LBCC也就是基于锁的机制来解决,也就是常说的行锁、表锁、间隙锁等。
基于对上述知识的理解,如果没有对Mysql不同事务隔离级别的底层实现原理有一个清晰认识的同学在回答这个问题的时候,要么就是很生硬,要么就是无法扩展,就会显得有点像是在背答案。
下面看看高手是怎么回答这个问题的吧。
高手:
在RR(也就是可重复读)的事务隔离级别下,InnoDB采用了MVCC机制来解决幻读问题。
MVCC就是一种乐观锁的机制,它通过对不同事务生成不同的快照版本,通过UNDO版本链进行管理并且在MVCC里面,规定了高版本能够看到低版本的事务变更,低版本看不到高版本的事务变更从而实现了不同事务之间的数据隔离,解决了幻读的问题。
但是在当前读的情况下,是直接读取内存的数据,跳过了快照度,所以还是会出现幻读问题。
我认为可以通过两个方式来解决。
第一种是尽量避免当前读的情况第二种是引入LBCC的方式
总结
好了,今天的分享就到这里结束了
如果喜欢我的作品,记得点赞、收藏、