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句法的

  • 相关阅读:
    开发一个基于 Android系统车载智能APP
    Xilium.CefGlue利用XHR实现Js调用c#方法
    WPF杂难解 奇怪的DisconnectedItem
    (转)获取安卓iOS上的微信聊天记录、通过Metasploit控制安卓
    mac 安装npm
    mac安装Homebrew
    关于面试,我也有说的
    【分享】小工具大智慧之Sql执行工具
    领域模型中分散的事务如何集中统一处理(C#解决方案)
    小程序大智慧,sqlserver 注释提取工具
  • 原文地址:https://www.cnblogs.com/fuwentao/p/7352989.html
Copyright © 2011-2022 走看看