文章目录
1. Read uncommitted(读未提交)
1.1定义
事务A读取到事务B未提交的数据
1.2 举例
A给B转账,本来是转5万,结果弄错转了10万,钱已经转了,但是A还没提交事务。
此时B去查看自己支付宝时发现到账10万高兴坏了。后来A发现不对马上回滚事务,然后再转账操作转了5万然后提交事务。
1.3 分析
B实际上收到5万,但他第一次查看时看到的是10万,那时他看到的是A还没提交的事务时的数据,这种情况就叫脏读。
2. Read committed(读提交)
2.1 定义
一个事务要等另一个事务提交后才能读取数据。
2.2 举例
B去买东西消费,卡里面有5万,刷卡机开启事务检测到B账户里有5万,就在这时A开了个事务把B账户里面的钱全取走了并提交了事务。当刷卡机准备扣款时再次检测B的余额发现没钱了(第二次读取数据要等A取钱事务提交后才能进行),扣款失败。
2.3 分析
以上就是读提交,如果有事务正在update数据时,读操作事务要等update事务提交后才能读取数据。
此时就解决了脏读问题,但是又引出了“不可重复读问题”,即一个事务范围内两次查询却得到不同的结果
3. Repeatable read(重复读)
3.1 定义
事务A读取数据未提交之前,不再允许其他事务修改数据
3.2 举例
B去买东西消费,卡里面有5万,刷卡机开启事务准备扣款,此时A开了个事务来取B的钱因为刷卡机的扣款事务还没提交,A事务想修改B账户的钱自然是失败的。此时刷卡机可以放心扣款。
3.3 分析
重复读解决了不可重复读问题,但是不可重复读是update操作引发的问题,而还有一种名叫幻读的情况,这个是insert/delete引起的,那该如何解决呢?
4. Serializable(序列化)
4.1 定义
最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
4.2 幻读情况举例
B今天出去shopping,总共花了2万,此时A开启事务查看B的消费,也看到的是B今天花了2万,就在这时B花了1万买了个新手机(insert一条新数据),并提交事务。此时A再来查看B的消费情况,发现多了1万消费。
A就疑惑啊,这1万拿来的?我出现幻觉了吗?这就是幻读情况。幻读可以通过设置“序列化”隔离级别清除。
注:大多数数据库默认的事务隔离级别是Read committed(读提交),比如Sql Server , Oracle。而Mysql的默认隔离级别是Repeatable read(可重复读)。
5. 事务隔离级别与出错情况
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
READ-UNCOMMITTED(读取未提交) | √ | √ | √ |
READ-COMMITTED(读取已提交) | × | √ | √ |
REPEATABLE-READ(可重复读) | × | × | √ |
SERIALIZABLE(可串行化) | × | × | × |