关于mysql隔离级别的文章太多太多了,本文也是从高性能Mysql上复制粘贴过来的,多数内容都是原文

四种隔离级别

  • READ UNCOMMITTED(能读到未提交的)
  • READ COMMITTED(只读取已提交的)
  • REPEATABLE READ(重复读取数据不会改变)
  • SERIALIZABLE(可串行化)


READ UNCOMMITTED(能读到未提交的)

在READ UNCOMMITTED级别, 在事务中可以查看其他事务中还没有提交的修改。这个隔离级别会导致很多问题, 从性能上来说, READ UNCOMMITTED不会比其他级别好太多, 却缺乏其他级别的很多好处, 除非有非常必要的理由, 在实际应用中一般很少使用。读取未提交的数据, 也称为脏读(dirty read) 。

READ COMMITTED(只读取已提交的)

大多数数据库系统的默认隔离级别是READ COMMITTED(但MySQL不是) 。READ COMMITTED满足前面提到的隔离性的简单定义: 一个事务可以看到其他事务在它开始之后提交的修改, 但在该事务提交之前, 其所做的任何修改对其他事务都是不可见的。 这个级别仍然允许不可重复读(nonrepeatable read) , 这意味着同一事务中两次执行相同查询条件的select语句, 可能会看到不同的数据结果。

REPEATABLE READ(重复读取数据不会改变)

这是MySQL默认的事务隔离级别

要想保证重复读取的数据不会改变,需要注意下面2个点
1.事务A读取指定的行(例如根据主键查询),再次读取该行的时候,此时应该与上一次数据一样,使用行级锁就能实现
2.事务A读取指定范围的数据,例如查询年龄10-20之间的用户,要保证下次读取的数据,返回的条数和上一次一样,这个使用行级锁实现不了,但是使用表锁又浪费性能
只有满足以上2点,才叫可重复读,如果仅仅满足1,不满足2,那么就叫做"可能产生幻读’
InnoDB和XtraDB存储引擎通过多版本并发控制(MVCC, Multiversion Concurrency Control) 解决了上述2个问题,那么反过来我们可以说:MVCC就是为了解决1和2而诞生的,这样说的话就更容易理解MVCC

SERIALIZABLE(可串行化)

这是最高的隔离级别。 该级别通过强制事务按序执行, 使不同事务之间不可能产生冲突, 从而解决了前面说的幻读问题。 简单来说, SERIALIZABLE会在读取的每一行数据上都加锁, 所以可能导致大量的超时和锁争用的问题。 实际应用中很少用到这个隔离级别, 除非需要严格确保数据安全且可以接受并发性能下降的结果。