数据库并发问题及事物隔离级别问题:脏读,不可重复读,幻读,第一类丢失更新,第二类丢失更新

来源:《spring 4 企业应用开发实战》

数据库并发问题:脏读,不可重复读,幻读,第一类丢失更新,第二类丢失更新

一个数据库,多个客户端并发访问数据库。在数据库中的相同数据可能被多个事物同时访问,如果没有采取必要的隔离措施,就会导致并发问题,破坏数据的完整性。这些问题可以归结为5类:3类数据库读问题,2类数据库更新问题。

1.脏读(dirty read)

A事物读取B事物尚未提交更改的数据,并在这个数据的基础上操作。如果B事物恰巧回滚,那么A事物读取到的事物是根本不被承认的。如下列:

时间 事物A 事物B
T1   开始事物
T2 开始事物  
T3   查询余额1000元
T4   取出500元,余额改为500元
T5 查询余额500元(脏读)  
T6   撤销事物余额1000元
T7 汇入100元,余额改为600元  
T8 提交事物  

在这个场景中B希望取出500元,而后又撤销了动作,而A往相同账户转入100元,就因为A读取到了B未提交更改数据,造成账户白白丢失500元。(注:在oracal数据库中,不会发生脏读的情况

2.不可重复读(unrepeatable read)

不可重复读是指:A事物读取到B事物已提交的更改数据。假设A在取款事物过程中,B往账户转入100元,A两次读取到的余额不一致。

时间 事物A 事物B
T1   开始事物
T2 开始事物  
T3   查询账户余额为1000元
T4 查询账户余额位1000元  
T5   取出100元,修改余额为900元
T6   提交事物
T7 查询账户余额900元(和T4查询不一致)  

同一事物中两次查询账户余额不一致

3.幻读(phantom read)

A事物读取B事物提交的新增数据,这时A事物将出现幻读

时间 事物A

事物B

T1   开始事物
T2 开始事物  
T3 统计账户总存款为10000元  
T4   新增一个存款账户,并转入100元
T5   提交事物
T6 再次统计存款为10100元(幻读)  

如果新增数据刚好满足查询条件,这个数据就会进入事物的视野,因而产生两次统计结果不一致的情况

注:幻读和不可重复读的区别在于前者读取到的是已提交的新增数据,后者读取到的是已提交的更新数据(或者删除的数据)。为了避免这两种情况,采取的策略是不同的,防止读到更改操作,只需要对操作数据添加行级锁,阻止操作中的数据发生变化;而防止读到新增数据,则往往添加表级锁--将整张表锁定,防止新增数据(Oracal通过多版本数据的方式实现)

4.第一类丢失数据更新

A事物撤销时,覆盖掉 B事物已提交的更新数据。

时间 事物A

事物B

T1   开始事物
T2 开始事物  
T3 查询账户为1000元  
T4   查询账户为1000元
T5   转入100元,修改余额为1100元
T6   提交事物
T7 取出100元,修改余额为900元  
T8 撤销事物(或提交事物)  
T9 余额回复为1000元(丢失更新)  

A事物在撤销时,将B事物转入的100元抹去了

5.第二类丢失更新

A事物覆盖B事物已提交的数据,造成B事物所有的操作丢失

时间 事物A

事物B

T1   开始事物
T2 开始事物  
T3 查询账户为1000元  
T4   查询账户为1000元
T5   取出100元,修改余额为900元
T6   提交事物
T7 转入100元  
T8 提交事物  
T9 修改余额为1100元(丢失更新)  

6.事物隔离级别及影响

猜你喜欢

转载自blog.csdn.net/cheng183/article/details/84941826
今日推荐