zoukankan      html  css  js  c++  java
  • MYSQL的锁介绍,以及死锁发生情况-带例子

      mysql锁能在并发情况下的mysql进行更好的优化

    MySQL有三种锁的级别:页级、表级、行级,这3种锁的特性可大致归纳如下: 
    表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
    行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
    页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

         由于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支持行级锁

    添加了(行级锁/表级锁)锁的数据不能被其它事务再锁定,也不被其它事务修改(修改、删除)

    是表级锁时,不管是否查询到记录,都会锁定表

    死锁:

    什么是死锁,在网上摘抄一段通俗的说法:

    老板要你做个事情,然后老板在等你做好后汇报结果给他。然后,现在你去忙这件事情了。在你还没做完这件事的时候,你的老板想再次的叫你做另一件事,于是,他到你的办公室找你,而你这时候已经做完前面的事情去了老板的办公室想汇报结果。你们两看到对方不在办公室,就在对方办公室一直等待,那么你就无法等到老板,你的老板也等不到你,这样就死锁了。

    解决办法,1、一般解决这样的情况,就是增加一个秘书,你开始做什么事情了。是否结束了。他都有记录。老板要下达命令前,先询问秘书就可以了。如果你正在忙,就稍微的等一会。这就是类似的情况。秘书相当于线程互斥的对象,用于同步两个线程。2、首先你要给线程(你自己一个手机,或者秘书)  然后尽量监测自己的状态是否死锁了。
    外围管理线程(你的老板也要有办法联系你,比如给你打电话)给你的消息队列插命令、 或者检查你执行了多少时间或者循环次数。是在不行就吧你杀了,再招一个工人 


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

    相关:

    mysql的锁表问题

    通过mysql show processlist 命令检查mysql锁的方法

  • 相关阅读:
    阻止事件冒泡
    移动端开发
    angular6 管道多参数传输 Pipe
    在div上添加小三角
    angular6 使用@Input() @Output()
    angular6 想要获取页面某些事件 如 点击 window宽高等等
    如何将项目添加到git上
    使用vue-cli 搭建element-admin后台
    bootstrap4 常用样式类名 (供自己参考)
    键盘按下 keyCode 的值
  • 原文地址:https://www.cnblogs.com/langtianya/p/5129779.html
Copyright © 2011-2022 走看看