丢失更新
示例:
Time | T1 | T2 |
---|---|---|
t1 | start | start |
t2 | SELECT m=100 | SELECT m=100 |
t3 | UPDATE m-=10 | |
t4 | UPDATE m+=20 | commit |
t5 | commit | |
t6 | (此时m=120) | (t3处的更新丢失) |
两个事务都对同一条记录的值进行了查询和更新操作,并先后提交,其中先提交的事务(T2)中的更新操作结果会被后提交的事务(T1)的更新操作结果覆盖。先提交的事务(T2)丢失更新。
脏读
示例:
Time | T1 | T2 |
---|---|---|
t1 | start | start |
t2 | SELECT m=100 | |
t3 | UPDATE m+=10 | |
t4 | SELECT m=110 | rollback |
t5 | 使用了110这个脏数据做某些操作或计算 | (此时m=100) |
一个事务(T1)内,读取到了一个记录的值并参与之后的计算。这个值是其它事务(T2)中更新后还未提交的,如果其它事务(T2)最终回滚,那么这个事务(T1)中读取并参与计算的值就成了脏数据。把事务(T1)的这次读取称为脏读。
不可重复读
Time | T1 | T2 |
---|---|---|
t1 | start | start |
t2 | SELECT m=100 | SELECT m=100 |
t3 | UPDATE m+=10 | |
t4 | commit | |
t4 | SELECT m=110 | |
t5 | (先后两次读取的值不一致) | (此时m=110) |
一个事务内,对同一条记录进行了前后两次查询,在这两次查询之间其它事务对该记录的值做了更新并提交操作,导致这两次查询的结果不一致。事务(T1)第一次的读取不可再之后重复。
幻读
Time | T1 | T2 |
---|---|---|
t1 | start | start |
t2 | SELECT id=12的记录(不存在) | |
t3 | INSERT id=12的记录 | |
t4 | commit | |
t5 | INSERT id=12的记录(主键冲突) | |
t6 | (id=12的记录的存在状态不一致) | (此时id=12的记录存在) |
一个事务内,由于其它事务(T2)的对一条记录的插入或删除操作导致当前事务(T2)得到这条记录的存在状态不一致。
MySQL的事务隔离级别
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncommitted | 可能 | 可能 | 可能 |
Read committed | 不可能 | 可能 | 可能 |
Repeatable read | 不可能 | 不可能 | 可能 |
Serializable | 不可能 | 不可能 | 不可能 |
--- EOF ---