简介
本文介绍MySQL的事务隔离级别的含义,并用示例说明各个级别会出现的问题:脏读、不可重复读、幻读。
MySQL有四种隔离级别:未提交读,提交读,可重复读,序列化。
事务的隔离级别是Java后端面试题中经常会问到的问题。
概述
隔离级别说明
高一级的级别提供更强的隔离性。标准允许事务运行在更强的事务隔离级别上。(如在可重复读(REPEATABLE READ)隔离级别上执行提交读(READ COMMITTED)的事务是没有问题的)。
以上除了序列化读以外,其他3种隔离级别都允许对同一条记录进行读-读、读-写、写-读的并发操作,如果我们不允许读-写、写-读的并发操作,可以使用SERIALIZABLE隔离级别。
隔离级别含义
√ 为会发生,×为不会发生。各个级别详细讲解见下方
隔离级别 | 英文名称 | 含义 | 脏读 | 不可重复读 | 幻读 |
未提交读 | READ UNCOMMITTED | 可读取其它事务未提交的结果 | √ | √ | √ |
提交读 | READ COMMITTED | 一个事务开始时,只能读到其他事务已经提交的修改。 例:如果A事务已经修改了XX,但还没提交,则B事务读XX时还是未修改的值。 (Oracle等多数数据库默认是该级别)。 | × | √ | √ |
可重复读 | REPEATABLE READ | 在开启事务时,同一条件的查询返回的结果是一样的。 例:A事务开启,查询一条记录;B事务更新这条记录并提交,A事务再次查询这条记录(查到的结果跟第一次查到的一样,而不是B修改过的结果)。 (MySQL默认级别) | × | × | √ |
可序列化 | SERIALIZABLE | 和repeatable-read类似。 不同点:若auto commit为false,那么每一条SELECT语句会自动被转化为SELECT ... LOCK IN SHARE MODE,这样会出现阻塞(如果别的事务已经修改了本事务要读的行,则本SELECT会阻塞(写加x锁,读加s锁))。 英文:This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... LOCK IN SHARE MODE if autocommit is disabled. If autocommit is enabled,the SELECT is its own transaction. It therefore is known to be read only and can be serialized if performed as a consistent (nonlocking) read and need not block for other transactions. (To force a plain SELECT to block if other transactions have modified the selected rows, disable autocommit.) | × | × | × |
说明:对于Spring,这些级别基本对应,其级别英文为:ISOLATION_DEFAULT(用底层数据库默认的隔离级别)、ISOLATION_READ_UNCOMMITTED、ISOLATION_READ_COMMITTED、ISOLATION_REPEATABLE_READ、ISOLATION_SERIALIZABLE