跳到主要内容

隔离级别

不同的隔离级别均以下面这张表为例子:

mysql> select * from students;
+----+-------+
| id | name |
+----+-------+
| 1 | Alice |
+----+-------+

DEFAULT

默认事务隔离级别,具体使用的隔离级别由数据库驱动决定。

  • 常量 Isolation.DEFAULT

脏读 (Read Uncommitted)

最低的隔离级别。事务 A 可以读到事务 B 更新后但未提交的数据。如果事务 B 回滚,事务 A 读到的就是脏数据。

  • 常量 Isolation.READ_UNCOMMITTED
时序事务 A事务 B效果
T1set isolation level read uncommitted
T2beginbegin
T3update students set name='bob' where id=1
T4select * from students where id=1读到 'bob'(脏读)
T5rollback
T6select * from students where id=1仍然读到 'Alice'

不可重复读 (Read Committed)

事务 A 只能读取到其他事务已提交的数据。但在同一事务中,两次相同查询可能返回不同结果(因为期间有其他事务提交了修改)。

  • 常量 Isolation.READ_COMMITTED
时序事务 A事务 B效果
T1set isolation level read committedset isolation level read committed
T2beginbegin
T3select * from students where id=1读到 'Alice'
T4update students set name='bob' where id=1
T5select * from students where id=1仍读到 'Alice'(未提交不可见)
T6commit
T7select * from students where id=1读到 'bob'(不可重复读)
T8commit

可重复读 (Repeatable Read)

在事务执行期间,相同的查询总是返回相同的结果,即使其他事务已提交了修改。

  • 常量 Isolation.REPEATABLE_READ
幻读

在 Repeatable Read 下,一个事务可能遇到幻读(Phantom Read): 第一次查询某条记录发现不存在,但当更新这条记录时却能成功,再次查询它就出现了。

时序事务 A事务 B效果
T1set isolation level repeatable readset isolation level repeatable read
T2beginbegin
T3select * from students where id=99结果为空
T4insert into students (id, name) values (99, 'bob')
T5commit
T6select * from students where id=99仍为空(可重复读)
T7update students set name='alice' where id=99更新成功
T8select * from students where id=99出现数据(幻读)

同步事务 (Serializable)

最高的隔离级别。事务序列化执行,不能并发。脏读、不可重复读、幻读都不会出现。

  • 常量 Isolation.SERIALIZABLE
性能影响

Serializable 相当于在开启事务时对整个数据库加 排他锁,直到事务提交后其他事务才能开始,效率会大大下降。 一般没有特别重要的场景不会使用此级别。

各级别对比

隔离级别脏读不可重复读幻读
READ_UNCOMMITTED可能可能可能
READ_COMMITTED-可能可能
REPEATABLE_READ--可能
SERIALIZABLE---