• Mysql中常见的锁


    加锁的目的就是保证共享资源在任意时间里,只有一个线程访问,这样就可以避免多线程导致共享数据错乱的问题。

    分类:

    操作数据的粒度分类:全局锁、表级锁、行锁

    数据操作的类型分类:

    1. 悲观锁:读锁(共享锁),写锁(排他锁)都不支持并发;
    2. 乐观锁:支持多线程并发,事务不需要排队,都可以对该数据进行修改,不过该数据需要有版本号,只有修改前和修改后的版本号一致才会修改成功,否则就会回滚。(先修改再验证) ,如在线文档
      只有在冲突概率非常低,且加锁成本非常高的场景时,才考虑使用乐观锁。

    锁的级别分类:

    1. 高级锁:读锁、写锁
    2. 低级锁: 互斥锁、自旋锁 (都是悲观锁)

    高级的锁都会由低级锁来实现,比如读写锁既可以选择互斥锁实现,也可以基于自旋锁实现。

    1. 全局锁

    执行后,整个数据库就处于只读状态了,DQL查询可用,DML和DDL不可用。

    场景

    全局锁主要应用于做全库逻辑备份,这样就不会因为数据或表结构的更新,而出现备份文件的数据与预期的不一样的情况。

    缺点: 粒度太大,造成业务停滞

    上锁:flush tables with read lock;
    解锁:unlock tables;

    2. 表锁

    InnoDb和MyISAM都支持;开销小,加锁快,粒度大,冲突概率高,并发度低下;

    上锁:
    lock tables 表名 read; (读锁)
    lock tables 表名 weite; (写锁)

    解锁:
    unlock tables;

    注意:当上读锁时,上锁的这个会话中也不能对该表进行写(DML、DDL)操作

    3. 行锁

    InnoDb引支持行级锁,MyISAM不支持,开销大,加锁慢,粒度小,冲突概率低,并发度高;

    上锁:
    select... where... lock in share mode;
    select... where... for update;

    3. 互斥锁和自旋锁

    当已经有一个线程加锁后,其他线程加锁则就会失败,互斥锁和自旋锁对于加锁失败后的处理方式是不一样的:

    • 互斥锁加锁失败后,线程会释放 CPU ,给其他线程;
    • 自旋锁加锁失败后,线程会忙等待,直到它拿到锁;

    互斥锁:
    互斥锁是一种「独占锁」,比如当线程 A 加锁成功后,此时互斥锁已经被线程 A 独占了,只要线程 A 没有释放手中的锁,线程 B 加锁就会失败,于是就会释放 CPU 让给其他线程,既然线程 B 释放掉了 CPU,自然线程 B 加锁的代码就会被阻塞态。
    对于互斥锁加锁失败而阻塞的现象,是由操作系统内核实现的。当加锁失败时,内核会将线程置为「睡眠」状态,等到锁被释放后,内核会在合适的时机唤醒线程,当这个线程成功获取到锁后,于是就可以继续执行。所以,互斥锁加锁失败时,会从用户态陷入到内核态,让内核帮我们切换线程,虽然简化了使用锁的难度,但是存在一定的性能开销成本。

    自旋锁:
    使用自旋锁的时候,当发生多线程竞争锁的情况,加锁失败的线程会「忙等待」,
    自旋锁是最比较简单的一种锁,一直自旋,利用 CPU 周期,直到锁可用,
    但如果被锁住的代码执行时间过长,自旋的线程会长时间占用 CPU 资源,

    比较:
    旋锁与互斥锁使用层面比较相似,但实现层面上完全不同:当加锁失败时,互斥锁用「线程切换」来应对,自旋锁则用「忙等待」来应对。

    它俩是锁的最基本处理方式,更高级的锁都会选择其中一个来实现,比如读写锁既可以选择互斥锁实现,也可以基于自旋锁实现,

    场景:
    互斥锁加锁失败会切换线程来应对,会增加开销;如果被锁住的代码的执行时间短,应该选择自旋锁,忙等待时间也短,开销小;

    参考:
    https://blog.csdn.net/qq_34827674/article/details/108608566
    https://xiaolincoding.com/mysql/lock/mysql_lock.html#%E5%85%A8%E5%B1%80%E9%94%81

  • 相关阅读:
    JavaEE平台技术——预备知识(Maven、Docker)
    【机械】二维钢桁架分析与设计附matlab代码
    Leetcode 206反转链表、3无重复字符的最长子串、912排序数组(快排)、215数组中的第k个最大元素、53最大子数组和、152乘积最大子数组
    JDBC连接池、JDBCTemplate
    【区块链实战】什么是 P2P 网络,区块链和 P2P 网络有什么关系
    【C语言刷LeetCode】395. 至少有 K 个重复字符的最长子串(M)
    Java设计模式:你见过大厂是怎么玩单列模式的吗?
    GEE两行代码下载任意范围影像python API
    HTML5期末大作业:游戏网站设计与实现——基于bootstrap响应式游戏资讯网站制作HTML+CSS+JavaScript
    Cloud Computing:云计算的简介之云计算的三层服务类型(从服务的层次)——IaaS、PaaS、SaaS的简介、核心技术之详细攻略
  • 原文地址:https://blog.csdn.net/Swofford/article/details/125553723