• mysql-4-锁机制


    1 场景

    库存等 共享资源等。 都需要锁,大量并发下,防止库存超卖等现象产生。

    2分类

     分类

    1:(读,写)锁:对数据操作的类型分类

     2: 对数据操作的粒度分 行锁,表锁

     读写锁

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

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

    三锁

    表锁(偏读):开销小,加锁快;无死锁,;锁粒度大,发生锁冲突概率大,并发低。

    行锁(偏写):和表锁都是对立的。

    页锁(介于中间):

        原因:表锁:直接将整个表锁住了。不像行锁要找到具体哪行,在锁住。所以表锁,开销小,加锁快,但是行锁并发高,具体并发到了某一行数据了。

    2.1 表锁

     查看所有的表上是否加过锁

    show open tables;

     查看已经锁住的表

    show OPEN TABLES where In_use > 0;

    手动添加表锁(t1表加读锁,t2表加写锁)

    lock table t1 read , t2 write;

     t1表加读锁

    lock table t1 read ;

     解所有表的锁

    unlock tables

     锁分析

    SHOW status like 'table%'

      自动提交事务关闭:

    set autocommit=0;

     查看间隙锁  参数默认值是OFF, 也就是启用间隙锁

    show variables like 'innodb_locks_unsafe_for_binlog';

    查看行锁的相关信息

    show status like 'innodb_row_lock%';

     

    3 表锁实战

    3.1 读锁实战

    场景:不知道

    读锁总结:

    session1 给 mylock 表加了读锁,session1 只能读 mylock表,更新 mylock表报错,查询别的表报错。

    其他session 干嘛都行,但是只要更新mylock表,会变成等待状态,一旦session1解锁,它将解除等待状态,他会立刻执行之前等待的那个update  sql 。

    步骤:

    1.  session1 执行 lock table mylock read ; 给 mylock 表加读锁
    2. session2 什么也不执行。
    3. session1 和 session2 都能查询 mylock 表的数据。不同的是,session1只能查 mylock表,session2所有表都能查。
    4. session1 更新 mylock表报错, session2 干什么都行,一旦 更新 mylock表,就会陷入等待状态,只要session1解锁,等待的sql就能执行成功。

     

    3.2  写锁实战

    总结:写锁是独享且限制锁

           加锁的session-----> 我只能对加锁的表任何sql,其他表一概不行。

          其他session----->我对其他表任何sql都行,加锁的表的任何sql 都将陷入等待状态,直到那个表解锁,sql就会自动执行成功。

      session1 给 mylock表加入写锁,只能对 mylock表的任何操作,其他表的操作不行。别的session对 mylock的任何sql都会陷入等待状态。知道session1解锁,立刻执行成功。

    4 行锁锁实战

    4.1 行锁实操

    1. CREATE TABLE `t1` (
    2. `t_id` int(20) NOT NULL,
    3. `t_name` varchar(20) DEFAULT NULL,
    4. PRIMARY KEY (`id`)
    5. ) ENGINE=InnoDB DEFAULT CHARSET=utf8

     

     

    自动提交事务关闭:

    set autocommit=0;
    session1session2解释
    set autocommit=0;set autocommit=0;都设置手动提交事务
    update t1 SET t_name='aa' WHERE t_id='1';更新id=1数据
    SELECT* from t1;事务隔离,还是只能看到之前的数据。
    update t1 SET t_name='bb' WHERE t_id='6';更新id不等1的数据都是可以的。
    update t1 SET t_name='bb' WHERE t_id='1';我也更新id=1的数据,会陷入等待状态。 行锁。
    COMMIT;
    更新id=1的sql,立刻执行成功。
    SELECT* from t1;因为是它自己提交事务的所以会查到,name='aa'
    SELECT* from t1;因为他还没有提交事务,但是它做了修改,所以查到的是 name='bb',如果没做修改。依然查不到name='aa',因为事务有隔离性。
    COMMIT;

     

     

    行锁升级为表锁:上述案例是在索引正常使用时,才会是行锁,一旦sql语句让索引失效,将会直接变成表锁,session2的 update将会直接陷入等待状态。

    4.2 手动为某一行数据加行锁(索引失效也是表锁)

    SELECT* from t1 where t_id=1 for update;

     for update_llllkccc的博客-CSDN博客_for update

     间隙锁

    总结:间隙锁,会锁定整个范围内的所有索引键值,即使这个索引键值不存在,也会被无辜的锁住,造成锁定的时候无法插入锁定键值的范围内的任何数据。在某些场景下造成很大的危害。

  • 相关阅读:
    [Ubuntu 20.04] HEIF图像格式与libheif库及其工具的使用
    关于入门深度学习mnist数据集前向计算的记录
    安卓期末大作业——售票APP源码和设计报告
    Java-Lambda表达式基本理解及使用
    零信任对企业安全防护能起到什么作用?
    Flink sql 写ddl连接kafka
    设计模式——模板方法
    MySQL学习(八)——锁
    vue2学习之前端路由小案例(后台管理小案例)
    Python自动化运维实战——Telnetlib和Netmiko自动化管理网络设备
  • 原文地址:https://blog.csdn.net/weixin_44383484/article/details/127976753