转载请注明出处:

1.按锁粒度分类:

  1. 行锁:锁某行数据,锁粒度最小,并发度高;; 行锁是指加锁的时候锁住的是表的某一行或多行记录,多个事务访问同一张表时,只有被锁住的记录不能访问,其他的记录可正常访问; 行锁是对所有行级别锁的一个统称,比如下面说的记录锁、间隙锁、临键锁都是属于行锁

  2. 表锁:锁整张表,锁粒度最大,并发度低; 上锁的时候锁住的是整个表,当下一个事务访问该表的时候,必须等前一个事务释放了锁才能进行对表进行访问;

  3. 间隙锁:锁的是一个区间

1.1什么情况会出现表锁

MySQL中的表锁主要是为了解决一些特殊情况下的并发问题而引入的,比如:

  1. ALTER TABLE操作:在执行ALTER TABLE操作时,MySQL会获取一个排它锁,防止其他事务对该表进行读写操作;

  2. 大事务操作:如果一个事务中包含大量的数据操作,比如更新或删除大量数据,那么MySQL会自动将该事务的隔离级别提升为SERIALIZABLE,也就是串行化,此时会对涉及到的所有表进行锁定,避免其他事务对该表的并发操作;

  3. 锁冲突较多:如果系统中存在较多的锁冲突,比如同一个表上有多个事务争夺同一个行锁或排它锁时,MySQL会自动将该表的锁级别提升为表锁,避免锁冲突的出现,提高系统的性能。 需要注意的是,表锁是对整张表进行锁定,因此会对其他事务的并发操作产生较大的影响,会导致系统的响应时间变慢,降低系统的并发性能。因此,在实际应用中,应该尽量避免使用表锁,而是采用行锁或其他更细粒度的锁机制来保证数据的一致性和并发性。

1.2什么情况会出现行锁

  MySQL中的行锁主要是为了保证并发读写的一致性而引入的,当多个事务同时对同一行进行读写操作时,MySQL就会自动对该行进行行级别的锁定,以保证数据的一致性。具体来说,会出现以下情况:

  1. UPDATE和DELETE操作:当使用UPDATE或DELETE语句更新或删除表中的某行数据时,MySQL会自动对该行进行排它锁定,避免其他事务同时对该行进行操作;

  2. INSERT操作:当使用INSERT语句插入新数据时,MySQL会自动对新插入的行进行共享锁定,避免其他事务对该行进行写操作;

  3. 查询操作:当使用SELECT ... FOR UPDATE语句进行查询时,MySQL会对查询结果所涉及到的所有行进行排它锁定,避免其他事务同时对该行进行操作;

  4. 锁冲突:当多个事务同时对同一行进行操作时,会产生锁冲突,此时MySQL会自动对该行进行行级别的锁定,以保证数据的一致性。 需要注意的是,行锁是对单行数据进行锁定,因此对系统的并发性能影响较小,但是在高并发和大数据量的情况下,可能会出现死锁和锁等待等问题,因此在实际应用中需要注意锁的细粒度和锁的使用场景,以避免出现性能问题。

1.3什么时候会出现间隙锁

  MySQL中的间隙锁是一种特殊的行锁,用于保证索引的一致性和避免幻读现象的出现。当执行范围查询操作时,MySQL会对查询范围内的所有行进行锁定,同时还会对查询范围之间的空隙或未被查询到的行进行间隙锁定,以保证数据的一致性。具体来说,会出现以下情况:

  1. 事务A向表中插入一行数据,此时MySQL会对该行进行行锁定;

  2. 事务B在相同的索引值处插入一行数据,此时MySQL会对该行进行行锁定,并对索引值范围之间的空隙进行间隙锁定,避免事务C在该范围内插入数据;

  3. 事务C在索引值范围内插入一行数据,此时MySQL会被阻塞,直到事务A或事务B提交或回滚,释放行锁和间隙锁,以避免幻读现象的出现。 需要注意的是,间隙锁会对系统的并发性能产生一定的影响,因此在实际应用中需要注意锁的细粒度和锁的使用场景,以避免出现性能问题。同时,在使用间隙锁时,需要注意锁的范围和锁的模式,以保证数据的一致性和并发性能。

2.按锁的作用范围分类

2.1 按锁的作用范围可以分为:

  • 乐观锁:并不会真正的去锁某行记录,而是通过一个版本号来实现的

  • 悲观锁:行锁、表锁等都是悲观锁

2.2 悲观锁

  (1) 概念 悲观锁,正如其名,具有强烈的独占和排他特性,每次去拿数据的时候都认为别人会修改,对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。

  (2) 应用场景 适用于并发量不大、写入操作比较频繁、数据一致性比较高的场景。但是由于需要频繁的加锁和解锁,可能会导致性能瓶颈。

  (3) 实现方式 在MySQL中使用悲观锁,必须关闭MySQL的自动提交,set autocommit=0。共享锁和排它锁是悲观锁的不同的实现,它俩都属于悲观锁的范畴。

    悲观锁的实现主要有两种方式:一种是使用SELECT ... FOR UPDATE语句,在读取数据时获得行级锁;另一种是使用SELECT ... LOCK IN SHARE MODE语句,在读取数据时获得共享锁。

  (4) 实战

  商品goods表中id,name,number分别代表商品ID,商品名称,商品库存。

2.3 乐观锁

  (1) 概念 乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。

  (2) 应用场景 适用于读多写少,因为如果出现大量的写操作,写冲突的可能性就会增大,业务层需要不断重试,会大大降低系统性能。

  (3) 实现方式

  乐观锁的实现主要有两种方式:一种是使用版本号,每个数据记录都有一个版本号,更新时需要比较版本号是否一致;另一种是使用CAS(Compare and Swap)操作,即比较并替换。

  版本比较的流程:一般使用数据版本(Version)记录机制实现,在数据库表中增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。

3.按锁的类型分类

3.1 按锁的类型分类

  • 共享锁(读锁):多个线程可以同时获取同一份数据的共享锁,读取数据但不能修改数据;

  • 排他锁(写锁):只允许一个线程获取排他锁,可以读取并修改数据。

3.2 共享锁

  共享锁(Shared Lock):共享锁是一种读锁,多个事务可以同时持有相同的共享锁,但是不能与排他锁同时存在。共享锁的主要作用是防止其他事务对数据进行修改,以保证事务的隔离性。在执行SELECT语句时,MySQL会自动加上共享锁,以避免其他事务对数据进行修改,但是不会阻塞其他事务的读取操作。

  实现方式:共享锁的实现方式是通过读锁实现的,即在读取数据时,使用LOCK IN SHARE MODE或SELECT ... FOR SHARE语句加上共享锁。

3.3 排它锁

  排他锁(Exclusive Lock):排他锁是一种写锁,一个事务持有排他锁时,其他事务不能持有共享锁或排他锁,以保证数据的独占性。在执行INSERT、UPDATE和DELETE等操作时,MySQL会自动加上排他锁,以避免其他事务对数据进行读取和修改。

  实现方式:排他锁的实现方式是通过写锁实现的,即在修改数据时,使用SELECT ... FOR UPDATE或UPDATE ... WHERE语句加上排他锁

 

mysql锁及锁出现总结的更多相关文章

  1. mysql 行级锁的使用以及死锁的预防

    一.前言 mysql的InnoDB,支持事务和行级锁,可以使用行锁来处理用户提现等业务.使用mysql锁的时候有时候会出现死锁,要做好死锁的预防. 二.MySQL行级锁 行级锁又分共享锁和排他锁. 共 ...

  2. mysql事务和锁InnoDB

    背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经常会收到MySQL锁相关的私信,让我帮助解决一些死锁的问题.本文,准备 ...

  3. 【MySQL】悲观锁&乐观锁

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.本文将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍. 悲观锁(Pessimistic Lock) 悲观锁的 ...

  4. MYSQL 解锁与锁表

    解锁 第一种 show processlist; 找到锁进程,kill id ; 第二种 mysql>UNLOCK TABLES; 锁表 锁定数据表,避免在备份过程中,表被更新 mysql> ...

  5. Mysql InnoDB行锁实现方式(转)

    Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点 ...

  6. Mysql InnoDB行锁实现方式

    Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点 ...

  7. mysql查看被锁住的表,正在进行的进程,已经杀掉进程的方法

    mysql查看被锁的进程 //查看所有进程show processlist; //查询是否锁表show OPEN TABLES where In_use > 0; //查看被锁住的 SELECT ...

  8. MySQL中的锁(表锁、行锁)

    锁是计算机协调多个进程或纯线程并发访问某一资源的机制.在数据库中,除传统的计算资源(CPU.RAM.I/O)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所在有数 ...

  9. MySQL行级锁,表级锁,页级锁详解

    页级:引擎 BDB. 表级:引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行 行级:引擎 INNODB , 单独的一行记录加锁 表级,直接锁定整张表,在你锁定期间,其它进程无法对该表进行写 ...

  10. mysql的锁--行锁,表锁,乐观锁,悲观锁

    一 引言--为什么mysql提供了锁 最近看到了mysql有行锁和表锁两个概念,越想越疑惑.为什么mysql要提供锁机制,而且这种机制不是一个摆设,还有很多人在用.在现代数据库里几乎有事务机制,aci ...

随机推荐

  1. Java中接口相关知识

    1.接口 1.1接口概述 接口就是一种公共的规范标准,只要符合标准,大家都可以通用 Java中的接口更多的体现在对行为的抽象 1.2接口的特点 接口用关键字interface修饰,格式:public ...

  2. LeetCode刷题4:寻找两个正序数组的中位数

    题目: 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2.请你找出并返回这两个正序数组的 中位数 . 算法的时间复杂度应该为 O(log (m+n)) . 来源:力扣 ...

  3. STM32F103使用FSMC对接正点原子3.5寸TFTLCD屏幕

    fsmc的使用算是32里面有点绕的一个知识点,但是想明白了其实也没啥了. 首先我先放32个0在这儿: 0000  0000  0000  0000  0000  0000  0000  0000 [3 ...

  4. 小米盒子TV变装魔法

    最近从一位台湾的朋友那里白嫖了一个 v2 节点, 恰好家里有一台家用的 小米盒子, 就寻思着能不能折腾一下, 共享上网 先将小米盒子开启adb调试, 参照这里: https://www.jb51.ne ...

  5. unittest框架基本使用

    1.简介 unittest是python内置的单元测试框架,具备编写用例.组织用例.执行用例.输出报告等自动化框架的条件.使用unittest前需要了解该框架的五个概念: 即test case,tes ...

  6. How to Install VMware Tools on CentOS 6.5

    yum install perl gcc make kernel-headers kernel-devel -y [root@centos6 vmware-tools-distrib]# ./vmwa ...

  7. Nginx配置ThinkPHP3.1的PATHINFO模式

    location / {    if (!-e $request_filename) {         rewrite ^/(.*)$ /index.php?$1 last;         bre ...

  8. 修改linux服务器时间

    date -s "20220104 11:07:05" &&hwclock --systohc

  9. python内置函数range()—对象创建函数

    range()函数 介绍 range()函数实际上表示一个不可变的数字序列类型,通常用于在for循环中指定特定的次数. range()的格式: range(stop) range(start, sto ...

  10. Redis内存淘汰策略

    目录 一.内存淘汰策略重要性 二.Key值过期策略 三.内存淘汰策略 三.Redis内存淘汰策略配置 一.内存淘汰策略重要性 我们都知道redis的性能很高,最主要的原因之一就是redis的数据都在内 ...