转载请注明出处:

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. vue中自动将px转换成rem

    1.首先下载 lib-flexible npm install lib-flexible --save 2.在main.js中引用 lib-flexible 3.安装px2rem-loader(将px ...

  2. android studio 控件

    在Android 开发中,需要使用的控件很多,除了TextView.Button.EditText,还有RadioGroup.CheckBox.Spinner.ImageView 等一大批控件.这些控 ...

  3. 初识 Linux Shell

    初识 Linux Shell 本书学习的第一步,就是要找到 Linux 终端的所在位置.目前较常见的图形化终端有 Konsole.Gnome terminal.xterm 等几种.一般安装后在各个发行 ...

  4. K8S的kubectl命令详解

    一.kubectl 基本命令 1.陈述式资源管理方法: 1.kubernetes集群管理集群资源的唯一入口是通过相应的方法调用apiserver的接口 2.kubectl 是官方的CLI命令行工具,用 ...

  5. C语言转义序列

    转义序列 含义 \a 报警(ANSIC) \b 退格 \f 换页 \n 换行 \r 回车 \t 水平制表符 \v 垂直制表符 \\ 反斜杆\ \' 单引号 \" 双引号 \? 问号 \0oo ...

  6. 【组会】2023_1_6 4d mmwave

    A NEW AUTOMOTIVE RADAR 4D POINT CLOUDS DETECTOR BY USING DEEP LEARNING ICASSP 2021 - 2021 IEEE Inter ...

  7. 什么是js柯里化(curry)?

    在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术. 举例来说,一个接收3个参数的普通函数,在进行柯里化后,柯里化版本的函数接收一个参数并返回接收下一个参数 ...

  8. C# Set集合

    包含不重复元素的集合称为"集(set)"..NET Framework包含两个集HashSet<T>和SortedSet<T>,它们都实现ISet<T ...

  9. 21206134-赵景涛-第三次blog总结

    一.前言: 本次Blog是对之前发布的PTA题目集的总结性Blog,这几次的作业题量,难度都不大,但都趋近于完成一整个系统,而非只实现部分的功能.题目集九.十也不在给出类图,而是要求自己设计.我认为这 ...

  10. ElasticSearch在linux环境安装和启动

    1.下载 https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-8-0 2.安装启动 2.1 错误1 Java HotSp ...