并发数据库事务缺锁导致的数据不一致情况:丢失更新,脏读,不可重复读,幻读

参考链接:  

https://www.cnblogs.com/lenther2002/p/4487123.html

http://www.jianshu.com/p/d8bc0a843dd0

http://blog.csdn.net/qq_36074150/article/details/76902737

https://www.cnblogs.com/itcomputer/articles/5133254.html

 

 

这些问题的出现的原因
之所以出现更新丢失,脏读,不可重复读,幻读,是因为当两个事务同时进行数据库操作的时候,两者之间互相不知道对方的存在,对自身所处的环境过分乐观,从而没有对操作的数据做一定的保护处理,最终导致一些问题的出现。

 

 

丢失更新:一个事务读取数据并提交修改,覆盖了从上次读取之后其他事务提交的修改(不是基于最新的数据进行修改)


图中:事务A在T6提交的120, 这个120是在T2读取的100的基础上加上20, 而此事务B已经将100改为110,  所以 此时提交120, 会将事务B的修改覆盖掉

解决方法:通过乐观锁可以解决这个问题,在T6提交阶段,先判断下原数据是否修改过

 

 

脏读:一个事务读到另外一个事务还没有提交的数据。

脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读出该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读到的数据是无效的。


图中,原始数据age位20, 事务b将其修改成21,此时尚未提交,事务A读取到age为21, 之后事务B又将修改撤销,  事务A读到的age=21是脏数据

 

 

解决方法:把事务隔离级别调整到read commited

 

 

不可重复读:一个事务2次读取一条记录之间有其他事务修改了改记录,导致2次读取的结果不一样

不可重复读:是指一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据,那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为不可重复读。

重点: 一条记录,  其他事务修改

图中,事务A第一次读取的age是20, 第二次读取的是21

 

解决方法:把事务隔离级别调整到REPEATABLE READ。

 

 

幻读:一个事务2次读取多条记录之间有其他事务进行了添加或删除的操作,导致2次读取记录的数量不一致

幻读和不可重复读类似,都是指2次读取的内容不一致,但是不可重复读是读取一条记录,而幻读是读取多条记录

重点:多条记录, 其他事务新增或删除

 


图中,事务A第一次查询有2条记录,第二次查询有3条记录。

 

解决方法:把事务隔离级别调整到SERIALIZABLE

 

 

读写提交

 




 


posted @ 2017-11-16 10:08  yfdream  阅读(2152)  评论(0编辑  收藏  举报