美文网首页
MySQL白菜教程(Level 9)

MySQL白菜教程(Level 9)

作者: 七喜丶 | 来源:发表于2021-08-22 14:32 被阅读0次

    锁的认识

    场景: 一个很久没有改动的访问量较低系统,由于访问增大忽然出现了一个问题,经过日志查看和代码排查发现原因如下

    • 表 A 主键:id,状态:status , 姓名: name
    • 表 B 主键:id,版本号:version ,累积总额:total
    表A 表B
    -- 小明 --
    start transaction;
    -- …… --
    update A set status = 2 where id= 1 and status =1;
    update B set total = total + XXX1 where id = 1 and version = 1;
    commit;
    
    -- 小红 --
    start transaction;
    -- …… --
    update A set status = 2 where id= 2 and status =1;
    update B set total = total + XXX2 where id = 1 and version = 1;
    commit;
    
    -- 张三 --
    start transaction;
    ……
    update A set status = 2 where id= 3 and status =1;
    update B set total = total + XXX3 where id = 1 and version = 1; 
    commit;
    

    表 A 的更新操作是用户订单状态完成的更新,表 B 的更新操作是业务上的统计
    很明显当并发产生时(多个事务去操作表 B 同一行数据)表 B 的更新会被乐观锁 version 控制住然后代码里判定更新失败并且抛出异常导致用户表A的更新被回滚
    问题不在于用了乐观锁,而是在于不相干的两个业务放到了一个事务里,统计和订单状态更新应该剥离开去做
    上面的问题导致了部分订单支付完成消息消费的延迟,重复很多次才被消费到,间隔时间较长,用户觉得已经扣款了订单为什么还没有成功

    总结一下 MySQL 中 InnoDB 的几种锁以及应用场景:

    mysql> show variables like '%isolation%';
    +-----------------------+-----------------+
    | Variable_name         | Value           |
    +-----------------------+-----------------+
    | transaction_isolation | REPEATABLE-READ |
    +-----------------------+-----------------+
    1 row in set (0.11 sec)
    

    MySQL 中 InnoDB 的事务隔离级别基本都是可重复度(REPEATABLE-READ)

    mysql> select version(); 
    +-----------+
    | version() |
    +-----------+
    | 8.0.17    |
    +-----------+
    1 row in set (0.01 sec)
    

    根据数据库的版本号在MySql官网找到InnoDB的锁


    Mysql官网链接

    锁的解释
    锁:计算机协调多个进程或线程并发访问某一资源的机制

    锁的重要性
    在数据库中,除了传统的计算资源(CPU、RAM、I\O等)的争抢,数据也是一种供多用户共享的资源
    因此,如何保证数据并发访问的一致性,有效性,是所有数据库必须要解决的问题
    锁冲突也是影响数据库并发访问性能的一个重要因素,因此锁对数据库尤其重要

    锁的缺点
    加锁是消耗资源的,锁的各种操作,包括:获得锁、检测锁是否已经解除、释放锁等,都会增加系统的开销

    相关文章

      网友评论

          本文标题:MySQL白菜教程(Level 9)

          本文链接:https://www.haomeiwen.com/subject/zynciltx.html