在MySQL的InnoDB引擎里,使用了临键锁来解决幻读的问题,所以实际上MySQL InnoDB引擎的可重复读隔离级别也没有幻读的问题。一般来说,隔离级别越高,性能越差,所以我之前在公司做的一个很重要的事情,就是推动隔离级别降低为已提交读。
这个回答的最后,就可以尝试把话题引导到下面的亮点方案中。
重点要描述清楚两方面的内容
- 推动公司把隔离级别从默认的可重复读降低为已提交读
- 在已提交读的基础上,万一需要利用可重复读的特性,该怎么办?
从前面的内容中你已经知道,MySQL 的默认隔离级别是可重复读,实际上互联网的很多应用都调整过这个隔离级别,降低为已提交读。那么你在面试的时候可以考虑使用这个来作为你的亮点方案。首先你要强调为什么要改。
最开始我来到公司的时候,我们的数据库隔离级别都是使用默认的隔离级别,也就是可重复读。但其实我们的业务场景很少利用可重复读的特性,比如说几乎全部事务内部对某一个数据都是只读一次的。
并且,可重复读比已提交读更加容易引起死锁的问题,比如说我们之前就出现过一个因为临键锁引发的死锁问题。而且已提交读的性能要比可重复读更好。所以综合之下,我就推动公司去调整隔离级别,将数据库的默认隔离级别降低为已提交读。
在这种情况下,面试官可能会追问你:“在调整了事务级别之后,万一需要可重复读的特性了,你怎么办?”
首先你要理解在什么样的场景下你才会需要可重复读这个隔离级别。
- 你需要在事务中发起两次同样的查询,并且你希望两次得到的结果是一样的。
- 你需要避开幻读,也就是事务开始之后,即便有别的事务插入了数据并且提交了,你也不希望读到这个新数据。
- 但是仔细想想,你真的存在这种场景吗?或者说,你真的没得选,以至于一定要使用可重复读这个隔离级别吗?
答案是几乎没有。大部分出现可重复读的需求都是因为代码没有写好,或者说至少可以通过改造业务来实现。比如说常见的可重复读,既然你需要读多次,那么自然可以在第一次读完之后缓存起来。