PS:MySQL的默认隔离级别为REPEATABLE READ(可重复读)
每种存储引擎对SQL标准中的四种隔离级别实现可能并不一致,这里仅对MySQL的InnoDB引擎的隔离级别做一下总结
一.READ UNCOMMITTED(未提交读)
在READ UNCOMMITTED级别中,事务的修改,即使没有提交,对其他事务也都是可见的。事务可以读取到未提交的数据,这也被称为脏读(Dirty Read)。这个级别会导致很多问题,从性能上来说,这个级别不会比其他级别好太多,但却缺乏其他级别的很多好处,除非真的有非常必要的理由,在实际应用中一般很少使用。
二.READ COMMITTED(提交读)
大多数数据库系统的默认隔离级别(但MySQL不是),
一个事务开始时只能“看见”已经提交事务所做的修改。换句话说,一个事务从开始到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也叫(nonrepeatable read)不可重复读,因为两次执行同样的查询,可能会得到不一样的结果
PS:在MyBatis框架中,在一个事务中MyBatis对同一个session多次查询同一个SQL会去使用缓存而不在查询数据库,这种情况可能会造成一些问题。
解决方案:
在xml文件 select语句添加 flushCache="true" ,告诉mybatis查询结束后刷新缓存,不记录查询结果到一级缓存中
本来想全局关闭,但在网上找的方案都不好使,如过有什么靠谱的方案可以告诉我哈。
三.REPEATABLE READ(可重复读)
这个级别为MySQL的默认隔离级别
这个级别解决了脏读的问题。改级别保证了在同一事务中多次读取同样记录的结果是一致的。但理论上,这个级别还是无法解决另外一个幻读(Phantom Read)的问题
所谓幻读指的 是 当某 个 事务 在读 取 某个 范围内 的 记录 时, 另外 一个 事务 又在 该 范围内 插入 了 新的 记录, 当 之前 的 事务 再次 读取 该 范围 的 记录 时, 会 产生 幻 行( Phantom Row)。
InnoDB存储引擎通过多版本并发控制(MVCC)解决了幻读的问题,这个可以在我的博客中找到,
关于幻读的讨论可以参考 Innodb 中 RR 隔离级别能否防止幻读?
MySQL关于可重复读的解释 官网文档
四.SERIALIZABLE(可串行化)
SERIALIZABLE 是最高的隔离级别。它通过强制事务串行执行,避免了前面说的幻读的问题。简单来说, SERIALIZABLE会在读取的每一行数据上都 加锁,所以可能导致大量的超时和锁争用的问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。
评论区