• [MySQL]对于事务并发处理带来的问题,脏读、不可重复读、幻读的理解


    一、缘由

      众所周知MySQL从5.5.8开始,Innodb就是默认的存储引擎,Innodb最大的特点是:支持事务、支持行级锁。

    既然支持事务,那么就会有处理并发事务带来的问题:更新丢失、脏读、不可重复读、幻读;相应的为了解决这四个问题,

    就产生了事务隔离级别:未提交读(Read uncommitted),已提交读(Read committed),可重复读(Repeatable read),可序列化(Serializable)。

      之前在看事务隔离级别的时候,基本是一知半解。再次碰到,还是浆糊,所以这里打算彻底搞明白、清楚,也好后续的学习。

    二、解决办法:

    1、概念说明:   

      更新丢失:最后的更新覆盖了其他事务之前的更新,而事务之间并不知道,发生更新丢失。更新丢失,可以完全避免,应用对访问的数据加锁即可。

      脏读:(针对未提交的数据)一个事务在更新一条记录,未提交前,第二个事务读到了第一个事务更新后的记录,那么第二个事务就读到了脏数据,会产生对第一个未提交

    数据的依赖。一旦第一个事务回滚,那么第二个事务读到的数据,将是错误的脏数据。

      不可重复读:(读取数据本身的对比)一个事务在读取某些数据后的一段时间后,再次读取这个数据,发现其读取出来的数据内容已经发生了改变,就是不可重复读。

      幻读:(读取结果集条数的对比)一个事务按相同的查询条件查询之前检索过的数据,确发现检索出来的结果集条数变多或者减少(由其他事务插入、删除的),类似产生幻觉。

    2、不可重复读和幻读的区别:

    不可重复读

    重点是修改:同样的条件下,你读取过的数据,再次读取发现值不一样了。

    例子:(只是为了说明区别,没有事务隔离级别约束)

    事务1:Jack读取自己的工资为1000,事务并没有结束:

    select salary from employee empId ="Jack"; 

    事务2:财务人员修改了Jack的工资为2000,并提交事务(事务1不知道):

    update employee set salary = 2000;

    commit;

    在事务1中,再次读取Jack的工资时,工资变为2000

    select salary from employee empId ="Jack";

    在一个事务中前后两次读取的结果值并不一致,导致了不可重读读

     

    幻读

    重点在于新增或者删除(数据条数的变化):同样条件下,第一次和第二次读出来的记录条数不一样。

    例子:

    目前工资为1000的员工有10人。

    事务1:读取所有工资为1000的员工,事务进行中

    select count(*) from employee where salary = 1000;

    共读取到10条记录。

    事务2:同时插入一条新的员工记录,工资也为1000

    insert into employee(empId, salary) values('Tom', 1000);

    commit;

    事务1:再次读取所有工资为1000的员工

    select count(*) from employee where salary = 1000;

    共读取到了11条记录,这样就像产生了幻读。

    三、事务隔离级别:

      并发处理带来的问题中,更新丢失可以完全避免,由应用对数据加锁即可。脏读、不可重读度、幻读,其实都是数据库的一致性问题,必须由一定的事务隔离机制来解决。

    其中一种方法是:不用加锁,通过一定的机制生成一个数据请求时间点的一致性快照,并用这个快照来提供一个界别的一致性读取。从用户的角度看,好像是数据库提偶拱了

    统一数据的多个版本。这种技术叫做:数据库多版本并发控制,MVCC 多版本数据库。

      事务隔离的本质是使事务在一定程度上串行化执行,显然和并发机制是矛盾的。数据库的事务隔离越严格,并发负作用越小,代价越高(影响并发访问了呗)。

      为了解决隔离和并大的矛盾,IOS SQL92规定了4个隔离级别。(隔离==串行

    MySQL 默认的级别是:Repeatable read 可重复读。

  • 相关阅读:
    JavaScript传递参数方法
    IScroll5不能滑到最底端的解决办法
    VS Less Compiler插件使用
    Sql查询某个字段是否包含小写字母
    试用VS2019正式版
    Ext.net MessageBox提示
    VS打开项目 提示Asp.net4.0未在web服务器上注册的解决方案
    罗技M185鼠标飘
    Ext.Net的一例Ext Undefined解决办法
    JGUI源码:DataTable固定列样式(20)
  • 原文地址:https://www.cnblogs.com/langdashu/p/6257160.html
Copyright © 2020-2023  润新知