zoukankan      html  css  js  c++  java
  • 并发数据库事务缺锁导致的数据不一致情况:丢失更新,脏读,不可重复读,幻读

    参考链接:  

    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

    读写提交




    
    
  • 相关阅读:
    计算小于12的阶乘
    ubuntu下gvim启动出现gtk warning Invalid input string
    UBUNTU基础知识
    Ubuntu下创建软链接
    linux命令行介绍及使用(二)
    Ubuntu问题sudo: /etc/sudoers is mode 0640should be 0440的解决方法
    安装mp3插件
    Ubuntu下GTK的安装
    linux命令行介绍及使用(三)
    VB.NET中用GDI+画饼图
  • 原文地址:https://www.cnblogs.com/yfdream/p/7842917.html
Copyright © 2011-2022 走看看