隔离级别是由现象来区分的。
如果不是序列化的操作,那么对于一个事务内特定的一些查询,由于其他的事务也可能会做更改,因此数据集可能是变化的。
由数据集变化的几种情况,定义了如下几种现象。
dirty read
如果一个事务,可以看到其他事务未提交的数据,就发生了dirty read。
示例:
Transaction | Action1 | Action2 | Action3 |
T1 | write(a) |
| rollback |
T2 |
| read(a) |
|
事务T2在Action2可以读到T1写的数据,这种情况就是dirty read。
non-repeatable read
如果一个事务在提交之前,它需要的数据可以被另一个事务修改或删除,那么则发生了non-repeatable read。
即,同一个事务在不同时间读取同一行,可能会读取到不同的数据。
示例:
Transaction | Action1 | Action2 | Action3 | Action4 |
T1 | read(a) |
|
| read(a) |
T2 |
| write/delete(a) | commit |
|
如果事务T1的两次read,获得的数据结果不同,这种现象就叫做non-repeatable read。
phantom read
如果一个事务中查询的结果集,在事务提交之前可以被其他事务更改,则发生了幻读。
示例:
Transaction | Action1 | Action2 | Action3 | Action4 |
T1 | select(criteria) |
|
| select(criteria) |
T2 |
| update/create (match to criteria) | commit |
|
如果事务T1两次的select(criteria)获得了不同的结果集,这种现象即是幻读。
隔离等级定义
基于以上三种现象,定义了如下四种隔离等级定义。
ISOLATION LEVEL | dirty read | non-repeatable read | phantom read |
Read uncommited | √ | √ | √ |
Read commited | × | √ | √ |
Repeatable read | × | × | √ |
Serializable | × | × | × |