zoukankan      html  css  js  c++  java
  • MySQL乐观锁为什么可以防止并发

    问题引入

    本文介绍的是最常用的也是mysql默认的innoDB引擎 Read committed隔离级别下事物的并发。这种情况下的事物特点是

    读:在一个事物里面的select语句 不会受到其他事物(不管其他事物有没有commit)的影响。

    写:对一条记录而言,一个事物一旦update一条记录,其他事物只能等待这个事物commit才能update那条记录

    举例并发分析:

    比如表中num字段=10 需要根据num字段的数值做一些业务处理

    事物A  begin   事物B begin  
    select num 得到10   
    根据结果10进行业务处理;  
    处理完之后 num减一 update table set num = num-1;  
    A 事物提交 commit; 此时num是9 此时A已经commit了
      select num 得到10 (此时的查询不受其它事物的影响)
      根据结果10进行业务处理;
      处理完之后 num减一  update table set num = num-1;
      会把num更新成8。
     结论: B以num是10的基础上 处理了众多逻辑,但是到update的时候 用到的b确是9 

    表格中 update table set num = num-1;会受到其他commit事物的影响(B事物把num从9更新成了8) 而select不会(查到的还是10)。

    1利用乐观锁处理事物的并发

      数据库增加一个锁的处理列(版本号),查询的时候多查一个版本号, update的时候 where条件附加一个版本号条件并且更新时候并且把版本号+1,处理流程

      1)select num,version from table;

      2)update table set num=num-1 ,version =version+1 where condition=? version=#{version

      3)Query OK, 1 rows affected (0.04 sec) | 注意:1 rows affected 

         update的时候 where条件附加一个版本号条件并且更新时候并且把版本号+1: update table set num=num-1 ,version =version+1 where condition=? version=#{version} 

      如果出现了查询时候的版本号和where条件的版本号不一致 说明其他事物并发影响到了版本号 version,此时update语句的影响行数(Query OK, 1 rows affected (0.04 sec))是0 然后做异常处理。()

    2把计算放到SQL中

    当我们把计算逻辑(比如钱的增量)写在SQL里面的时候 可以不用乐观锁,因为SQL增量时会读到其他已经提交的事物。

    注意:一条记录,一个事物update还未提交的时候,其他时候只能等待这个事物commit完成才能update

    乐观锁处理并发的原理 重点

    当事物的隔离级别是REPEATABLE_READ情况下:当前事物不能select到并发事物中已经提交的事物。

    当事物的隔离级别是READ COMMITTED情况下:当前事物select到并发事物中已经提交的事物。

    1)一个事物中的select语句可能不会收到其他事物的影响,也就是可能查不到其他并发中未提交的事物(即使提交了 如果是REPEATABLE_READ也查不到)。所以两个事物共同执行时产生了并发的冲突。

    2)虽然这个被并发的字段通过select查不出来,但是在where条件语句中 这个字段会受到其他事物的影响 。所以可以利用这点 可以读到并发事物影响的数据 ,从而做出判断,防止并发。

    补充:共享锁与排他锁

    --共享锁:对某一资源加共享锁,自身可以读该资源,其他人也可以读该资源

    (也可以再继续加共享锁,即 共享锁可多个共存),但无法修改。要想修改就必须等所有共享锁都释放完之后。语法为:

    select * from table lock in share mode

    --排他锁:对某一资源加排他锁,自身可以进行增删改查,其他人无法进行任何操作。语法为:

    select * from table for update (A select for update的时候 B可以select 但不能select for update  排它锁只有一把)

    数据库的增删改操作默认都会加排他锁,而查询不会加任何锁。

  • 相关阅读:
    jsp mysql 配置线程池
    服务端 模拟 检测 攻击。。乱写
    硕思闪客精灵 7.2 破解版
    unity UnityAwe 插件
    smartfoxserver 2x 解决 Math NAN
    unity 断点下载
    java 监听文件目录修改
    wind7 64 setup appjs
    sfs2x 修改jvm 内存
    unity ngui 解决图层问题
  • 原文地址:https://www.cnblogs.com/ssskkk/p/8673374.html
Copyright © 2011-2022 走看看