首页 > 数据库 >mysql锁及锁出现总结

mysql锁及锁出现总结

时间:2023-04-10 09:55:35浏览次数:46  
标签:总结 事务 行锁 mysql 锁及 并发 MySQL 共享 数据

转载请注明出处:

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,锁及,并发,MySQL,共享,数据
From: https://www.cnblogs.com/zjdxr-up/p/17301867.html

相关文章

  • 5 分钟带你小程序入门 [实战总结分享]
    微信小程序常常用4种文件类型JS文件JS在小程序中用于编写页面逻辑和交互效果,可调用API接口完成数据请求和处理,也可以使用第三方库和框架。模块化编程:小程序中JS文件可以使用ES6的模块化语法,通过export和import来导出和导入模块。引用其他JS文件:小程序中的JS文件可以......
  • 今日总结(3.22 具体功能实现)
    切换城市packagecom.example.app_t;importandroidx.appcompat.app.AppCompatActivity;importandroid.content.Intent;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.Button;publicclassMainActivity2extendsAppCompatActivityimpl......
  • MySQL启用跟踪MDL(元数据锁)功能
     MySQL启用跟踪MDL(元数据锁)功能 MDL锁:全称为metadatalock,中文叫元数据锁,是从MySQL5.5开始引入的锁,是为了解决DDL操作和DML操作之间操作一致性。从锁的作用范围上来说,MDL算是一种表级锁,是一个server层的锁。其实MDL加锁过程是系统自动控制,无法直接干预,也不需要直接干......
  • MySQL、Oracle、SQLServer、PostgreSQL、DB2、Sybase、GBase、Informix关系型数据库简
    MySQLMySQL是一种开源的关系型数据库管理系统,它是最流行的数据库之一。MySQL具有高性能、可靠性和易用性的特点,支持多种操作系统和编程语言。MySQL的优点包括:优点:开源免费,可自由使用和修改高性能,支持大规模数据存储和高并发访问易于安装和使用,具有良好的文档和社区支持支......
  • 4月6日总结
    计算机视觉任务之图像分类将图像表示为三维的数组形式,每个像素由0到255,像素值越低颜色越深,越高越浅K进领算法通俗语言,分析一个人的形象,根据常和他在一起的人的形象判断,进行大致的推测。算法流程1计算已知类别数据集中的点与当前点的距离2按距离依次排序3选取与当前点距离......
  • 4月5日总结
    GeoJSON文件合并普通的geoJSON文件合并,只需geojson-merge插件就够了,https://www.npmjs.com/package/@mapbox/geojson-mergemergeFeatureCollectionStream合并文件MergeGeoJSONfilescontainingGeoJSONFeatureCollectionsintoasinglestreamofaFeatureCollectionas......
  • 4月4日总结
    B.PhoenixandBeauty要求所有长度为k的子数组之和相同,观察样例可以发现,当原数组中不同的元素个数小于等于k时可以满足条件,同时输出的数组长度m很大,可以从这里入手构造一个有所有元素的数组,当这个数组长度不足时,补其他元素进去,答案即为10000k个这样的数组为什么这样的数......
  • 4月3日总结
    数据结构学习简单了解一下时间复杂度之类之后,我们接下来学习下面的持续更完,本人依据知识框架结合chatgpt的定义总结线性表线性表是最基本的一种线性数据结构设某个线性表中有n个元素,n表示该线性表的长度。我们想象一个磁条,上面是一格格的储存块,我们要存储一个线性数据结构......
  • 近万字总结:Java8 Stream流式处理指南
    总结/朱季谦在实际项目当中,若能熟练使用Java8的Stream流特性进行开发,就比较容易写出简洁优雅的代码。目前市面上很多开源框架,如Mybatis-Plus、kafkaStreams以及Flink流处理等,都有一个相似的地方,即用到Stream流特性,其写出的代码简洁而易懂,当然,若是在不熟悉流特性的基础上而贸......
  • mysql的主键超过最大值会发生什么?
    设置主键的情况下在自增主键达到int64最大后,再次插入一行记录,报错如下:Duplicateentry‘4294967295’forkey‘increment_id_test.PRIMARY’唯一键冲突报错:当auto_incement达到上限后,再次申请下一个id时,得到的值保持不变。在建表时,通常都会将主键id设置为8字节的bigintu......