zoukankan      html  css  js  c++  java
  • 关于mysql数据库引擎InnoDB事务的表锁和行锁理解

     例子1:

    在电子商务里,经常会出现库存数量少,购买的人又特别多,大并发情况下如何确保商品数量不会被多次购买.

        其实很简单,利用事务+for update就可以解决. (for update仅仅适用于InnoDB)

    我们都知道for update实际上是共享锁,是可以被读取的.但是如何在执行时,不被读取呢.

    简单来说:假设现在库存为1,现在有A和B同时购买

       先开启一个事务

    begin;

    select stock from good where id=1 for update;//查询good表某个商品中stock的数量

      查出来后,在程序里在判断这个stock是否为0(你用什么语言,不关我事)

    最后在执行

    update good set stock=stock-1 where id=1

    最后在

    commit

        但是这个时候B也是select stock from good where id=1 for update;注意:for update不能省略..这个时候会出现被锁住,无法被读取.

    所以这就能够保证了商品剩余数量为1的一致性.

     

    例子2:

     由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例) ,否则MySQL将会执行Table Lock (将整个资料表单给锁住)。
    举个例子:
    假设有个表单products ,里面有id跟name二个栏位,id是主键。
    例1: (明确指定主键,并且有此笔资料,row lock)
    SELECT * FROM products WHERE id='3' FOR UPDATE;
    SELECT * FROM products WHERE id='3' and type=1 FOR UPDATE;

    例2: (明确指定主键,若查无此笔资料,无lock)
    SELECT * FROM products WHERE id='-1' FOR UPDATE;

    例2: (无主键,table lock)
    SELECT * FROM products WHERE name='Mouse' FOR UPDATE;

    例3: (主键不明确,table lock)
    SELECT * FROM products WHERE id<>'3' FOR UPDATE;

    例4: (主键不明确,table lock)
    SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;

    注1: FOR UPDATE仅适用于InnoDB,且必须在交易区块(BEGIN/COMMIT)中才能生效。
    注2: 要测试锁定的状况,可以利用MySQL的Command Mode ,开二个视窗来做测试。

    在MySql 5.0中测试确实是这样的
    另外:MyAsim 只支持表级锁,InnerDB支持行级锁
    添加了(行级锁/表级锁)锁的数据不能被其它事务再锁定,也不被其它事务修改(修改、删除)
    是表级锁时,不管是否查询到记录,都会锁定表

    此外,如果A与B都对表id进行查询但查询不到记录,则A与B在查询上不会进行row锁,但A与B都会获取排它锁,此时A再插入一条记录的话则会因为B已经有锁而处于等待中,此时B再插入一条同样的数据则会抛出Deadlock found when trying to get lock; try restarting transaction然后释放锁,此时A就获得了锁而插入成功


    上面介绍过SELECT ... FOR UPDATE 的用法,不过锁定(Lock)的数据是判别就得要注意一下了。由于InnoDB 预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则mysql 将会执行Table Lock (将整个数据表单给锁住)。


    注意:之前orcale中使用过nowait关键字,以为在mySQL中也可以,但是结果却不是这样的。原因是:目前builtin版本的innodb不支持nowait句法的

  • 相关阅读:
    剑指Offer-30.连续子数组的最大和(C++/Java)
    剑指Offer-29.最小的K个数(C++/Java)
    UVA 1616 Caravan Robbers 商队抢劫者(二分)
    UVA 10570 Meeting with Aliens 外星人聚会
    UVA 11093 Just Finish it up 环形跑道 (贪心)
    UVA 12673 Erratic Expansion 奇怪的气球膨胀 (递推)
    UVA 10954 Add All 全部相加 (Huffman编码)
    UVA 714 Copying Books 抄书 (二分)
    UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
    codeforecs Gym 100286B Blind Walk
  • 原文地址:https://www.cnblogs.com/fuwentao/p/7352989.html
Copyright © 2011-2022 走看看