我们经常说的事务隔离级别,一般指的是SQL-92标准中定义的四个级别。分别是:
- Read Uncommitted 未提交读
- Read Committed 提交读
- Repeatable Read 可重复读
- Serializable 序列化
- Read Uncommitted 未提交读
事务A更新了数据,但没有提交(commit),允许事务B读到这条变化的数据。如果事务A最终没有提交,而是rollback回原来的状态,那么事务B读到的数据就是一条脏数据。
图1 未提交读
- Read Committed 提交读
事务A在更新数据并且提交后,才允许事务B读取到,这样就可以避免脏读。
图2 提交读
Read Committed并不能防止不可重复读和幻读,什么是不可重复读和幻读?看下图
不可重复读是事务B在多次读取数据过程中,事务A对数据进行更新或者删除,导致事务B前后读到的数据不一致。
图3 不可重复读
幻读是事务B在多次读取过程中,事务A对数据新增了,导致事务B后读的数据比之前读的多了,感觉像是凭空出来的一样。
图4 幻读
- Repeatable Read 可重复读
图5 可重复读
显然,要实现可重复读,需要事务B在读取数据后,对SELECT的数据加锁,事务A不能修改,这可以通过“共享读锁”和“排它写锁”来实现。可重复读不能避免幻读。
- Serializable 序列化
提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。这样可以避免幻读,但是,这样的事务级别,性能也最差。
图6 序列化事务
下面是隔离级别及其对应的可能出现或不可能出现的现象
| Dirty Read | NonRepeatable Read | Phantom Read |
Read uncommitted | Possible | Possible | Possible |
Read committed | Not possible | Possible | Possible |
Repeatable read | Not possible | Not possible | Possible |
Serializable | Not possible | Not possible | Not possible |