zoukankan      html  css  js  c++  java
  • mysql高级(锁机制)

    录:

    1、锁分类
    2、表锁
        2.1、表锁--加读锁
        2.2、表锁--加写锁
        2.3、总结
        2.4、表锁定的统计信息
    3、行锁
        3.1、不能读取未提交的数据
        3.2、不同线程更新同一条记录,后更新的被阻塞
    4、索引失效导致行锁变表锁
    5、间隙锁的危害
    6、如何锁定一行
    7、如何分析行锁的统计信息

    1、锁分类    <--返回目录

      从对数据操作的类型分类:

        1)读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会相互影响。

        2)写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。

      从对数据操作的粒度分类:表锁(偏读)、行锁(偏写)、页锁

    2、表锁    <--返回目录

      表锁特点:偏向MyISAM存储引擎,开销小,加锁快;无死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

      演示建表SQL:

    create table mylock(
        id int not null primary key auto_increment,
        name varchar(20)
    )engine myisam;
    insert into mylock(name) values('a');
    insert into mylock(name) values('b');
    insert into mylock(name) values('c');
    insert into mylock(name) values('d');
    insert into mylock(name) values('e');

      手动增加表锁:lock table 表名1 read[write], 表名2 read[write];

      查看表上的锁:show open tables;     in_use 为1表示有锁

       删除所有锁:unlock tables;

    2.1、表锁--加读锁    <--返回目录

      会话1给mylock表添加读锁,会话1可以读mylock表,不可以更新mylock表;会话2可以读mylock表,更新mylock表时被阻塞,等待会话1解锁。

       会话2给mylock表加读锁后,在没有解锁前,不可以读其他表;会话2可以读其他表。

    2.2、表锁--加写锁    <--返回目录

      会话2给mylock表添加写锁,会话1可以读和写mylock表,不可以读写其他表;并且阻塞其他会话对mylock表的读和写。

    2.3、总结    <--返回目录

      MyISAM是表锁:执行select给表加表读锁,执行增删改给表加表写锁。

      读锁会阻塞  其他会话  对加了读锁的表的写操作,但不会阻塞读操作;写锁会阻塞  其他会话  读和写。

    2.4、表锁定的统计信息    <--返回目录

      查看哪些表被加锁了:show open tables;

      分析表锁定的次数:show status like ''table%;

      此外,MyISAM的读写锁调度是写优先,这也是MyISAM不适合做写操作为主的引擎。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞。

    3、行锁    <--返回目录

      行锁特点:偏向InnoDB存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

      InnoDB与MyISAM的最大不同有两点:一是支持事务;二是采用了行级锁。

      演示建表SQL:

    create table innodb_lock(
        a int not null primary key auto_increment,
        b varchar(20)
    )engine innodb;
    insert into innodb_lock(b) values('b1');
    insert into innodb_lock(b) values('b2');
    insert into innodb_lock(b) values('3');
    insert into innodb_lock(b) values('4000');
    insert into innodb_lock(b) values('5000');
    insert into innodb_lock(b) values('6000');
    insert into innodb_lock(b) values('7000');
    
    create index innodb_lock_a on innodb_lock(a);
    create index innodb_lock_b on innodb_lock(b);

      关闭自动提交:set autocommit=0;

      查看:show variables like 'autocommit';

    3.1、不能读取未提交的数据    <--返回目录

      会话1可以查看到自己更新的记录,其他会话无法查看到(会话1未提交的记录)

       会话1commit后,会话2才能查看到更新的数据

    3.2、不同线程更新同一条记录,后更新的被阻塞    <--返回目录

      会话1未commit前,会话2更新相同的记录(被会话1行锁锁定了)会被阻塞

     

     

    4、索引失效导致行锁变表锁    <--返回目录

      正常情况下,会话1更新记录b=‘5000’(原来a=5),会话2更新记录a=1,互不干扰。

      如果会话1SQL使用不当,索引失效从而导致行锁变表锁,则会阻塞会话2的更新操作

     

    5、间隙锁的危害    <--返回目录

      会话1更新 a>1 and a<200的记录,导致会话2插入阻塞

     

      会话1 更新条件 a>1也会导致其他会话更新阻塞

    6、如何锁定一行    <--返回目录

      begin;

      select * from 表名 where id=xxx for update;

      commit;

    7、如何分析行锁的统计信息    <--返回目录

      show status like 'innodb_row_lock%';

       ---

  • 相关阅读:
    APP界面设计之尺寸介绍
    设计师应该知道的那些事儿(一)
    PS制作高光导航背景
    URL长度限制
    问自己的技术问题
    JavaScript实现生成GUID(全局统一标识符)
    JS操作数组,for循环新技能get
    win7/Win8/Win10, IIS7.5/IIS8/IIS10 配置伪静态
    .NET WebAPI生成Excel
    .net WebAPI 传递对象参数
  • 原文地址:https://www.cnblogs.com/xy-ouyang/p/13342233.html
Copyright © 2011-2022 走看看