当前位置: 首页 > article >正文

MySQL进阶_10.锁

文章目录

  • 一、概述
  • 二、MySQL并发事务访问相同记录
    • 2.1、读-读
    • 2.2、写-写
    • 2.3、读-写
    • 2.4、并发问题的解决方案
  • 三、锁的不同角度分类
    • 3.1、 读锁、写锁
      • 3.1.1、 锁定读
    • 3.2、表级锁、页级锁、行锁
      • 3.2.1、表锁
      • 3.2.2、意向锁
        • 3.2.2.1、意向锁的作用
        • 3.2.2.2、意向锁的互斥性
      • 3.2.3、自增锁(AUTO-INC锁)
      • 3.2.4、元数据锁(MDL锁)

一、概述

在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。为保证数据的一致性,需要对 并发操作进行控制 ,因此产生了 。同时 锁机制 也为实现MySQL的各个隔离级别提供了保证。 锁冲突 也是影响数据库 并发访问性能 的一个重要因素。所以锁对数据库而言显得尤其重要,也更加复杂。

二、MySQL并发事务访问相同记录

并发事务访问相同记录的情况大致可以划分为3种

2.1、读-读

读-读 情况,即并发事务相继 读取相同的记录 。读取操作本身不会对记录有任何影响,并不会引起什么问题,所以允许这种情况的发生

2.2、写-写

有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失第二类更新丢失

2.3、读-写

有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读幻读不可重复读

2.4、并发问题的解决方案

怎么解决 脏读 、 不可重复读 、 幻读 这些问题呢?其实有两种可选的解决方案

  1. 读操作利用多版本并发控制( MVCC ),写操作进行 加锁
  2. 读、写操作都采用 加锁 的方式

采用 MVCC 方式的话, 读-写 操作彼此并不冲突, 性能更高。采用 加锁 方式的话, 读-写 操作彼此需要 排队执行 ,影响性能。

三、锁的不同角度分类

在这里插入图片描述

3.1、 读锁、写锁

  • 读锁 :也称为 共享锁 、英文用 S 表示。针对同一份数据,多个事务的读操作可以同时进行而不会互相影响,相互不阻塞的。
  • 写锁 :也称为 排他锁 、英文用 X 表示。当前写操作没有完成前,它会阻断其他写锁和读锁。这样就能确保在给定的时间里,只有一个事务能执行写入,并防止其他用户读取正在写入的同一资源。

需要注意的是对于 InnoDB 引擎来说,读锁和写锁可以加在表上,也可以加在行上

3.1.1、 锁定读

SELECT ... LOCK IN SHARE MODE;
#或
SELECT ... FOR SHARE; #(8.0新增语法)

在普通的SELECT语句后边加LOCK IN SHARE MODE,如果当前事务执行了该语句,那么它会为读取到的记录加S锁。

SELECT ... FOR UPDATE;

在普通的SELECT语句后边加FOR UPDATE,如果当前事务执行了该语句,那么它会为读取到的记录加X锁。这样既不允许别的事务获取这些记录的S锁,也不允许获取这些记录的X锁。如果别的事务想获取这些记录的S锁或X锁,那么它们会阻塞,直到当前事务提交之后将这些记录上的X锁释放掉。

3.2、表级锁、页级锁、行锁

  为了尽可能提高数据库的并发度,每次锁定的数据范围越小越好,理论上每次只锁定当前操作的数据的方案会得到最大的并发度,但是管理锁是很耗资源的事情(涉及获取、检查、释放锁等动作)。因此数据库系统需要在高并发响应系统性能两方面进行平衡,这样就产生了“锁粒度(Lock granularity)”的概念。
  对一条记录加锁影响的也只是这条记录而已,我们就说这个锁的粒度比较细;其实一个事务也可以在表级别进行加锁,自然就被称之为表级锁或者表锁,对一个表加锁影响整个表中的记录,我们就说这个锁的粒度比较粗。锁的粒度主要分为表级锁、页级锁和行锁。

3.2.1、表锁

在这里插入图片描述

3.2.2、意向锁

3.2.2.1、意向锁的作用

  InnoDB 支持 多粒度锁(multiple granularity locking) ,它允许 行级锁表级锁 共存,而意向锁就是能和行级锁共存的一种 表锁

意向锁解决的问题是:
  现在有两个事务,分别是T1和T2,其中T2试图在该表级别上应用共享或排它锁,如果没有意向锁存在,那么T2就需要去检查各个页或行是否存在锁(假设表中数据有100000行,是很费时间的);如果存在意向锁,那么此时就会受到由T1控制的表级别意向锁的阻塞。T2在锁定该表前不必检查各个页或行锁,而只需检查表上的意向锁。简单来说就是给更大一级别的空间示意里面是否已经上过锁。
  在数据表的场景中,如果我们给某一行数据加上了排它锁,数据库会自动给更大一级的空间,比如数据页或数据表加上意向锁,告诉其他人这个数据页或数据表已经有人上过排它锁了,这样当其他人想要获取数据表排它锁的时候,只需要了解是否有人已经获取了这个数据表的意向排他锁即可。

意向锁分为两种:

  • 意向共享锁(intention shared lock, IS):事务有意向对表中的某些行加共享锁(S锁)
-- 事务要获取某些行的 S 锁,必须先获得表的 IS 锁。
SELECT column FROM table ... LOCK IN SHARE MODE;

-- 假设本次查询只对三条数据加了S锁,InnoDB会自动给该表加IS锁
  • 意向排他锁(intention exclusive lock, IX):事务有意向对表中的某些行加排他锁(X锁)
-- 事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
SELECT column FROM table ... FOR UPDATE;

即:意向锁是由存储引擎 自己维护的 ,用户无法手动操作意向锁,在为数据行加共享 / 排他锁之前,InooDB 会先获取该数据行 所在数据表的对应意向锁

3.2.2.2、意向锁的互斥性

在这里插入图片描述
即意向锁之间是互相兼容的,虽然意向锁和自家兄弟互相兼容,但是它会与普通的排他/共享锁互斥。

在这里插入图片描述
注意这里的排他/共享锁指的都是表锁意向锁不会与行级的共享/排他锁互斥
IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的x,s发生冲突。

3.2.3、自增锁(AUTO-INC锁)

本次学习不做了解。

3.2.4、元数据锁(MDL锁)


http://www.kler.cn/a/145703.html

相关文章:

  • Web安全攻防入门教程——hvv行动详解
  • 62,【2】 BUUCTF WEB [强网杯 2019]Upload1
  • Jenkins-pipeline语法说明
  • T-SQL语言的数据库编程
  • 2025/1/21 学习Vue的第四天
  • Linux:进程(三)
  • 《已解决: ImportError: Keras requires TensorFlow 2.2 or higher 问题》
  • Docker部署Nacos
  • ubuntu22.04安装swagboot遇到的问题
  • 【2023.11.26】Mybatis自定义映射规则学习
  • 手机APP-MCP走蓝牙无线遥控智能安全帽~执法记录仪~拍照录像,并可做基础的配置,例如修改服务器IP以及配置WiFi等
  • 开源博客项目Blog .NET Core源码学习(7:FluentValidation使用浅析)
  • 使用 Raspberry Pi、Golang 和 HERE XYZ 制作实时地图
  • 2023亚太杯数学建模思路 - 案例:粒子群算法
  • 为什么PCB板大多数都是绿色的?
  • Android获取原始图片Bitmap的宽高大小尺寸,Kotlin
  • Spark的通用运行流程与Spark YARN Cluster 模式的运行流程
  • 粒子群算法Particle Swarm Optimization (PSO)的定义,应用优点和缺点的总结!!
  • 【Jenkins】jenkins发送邮件报错:Not sent to the following valid addresses:
  • 线程的状态以及状态转移
  • Docker 部署 Nacos(单机),利用 MySQL 数据库存储配置信息
  • jpa创建自定义UUID,且符合IETF RFC 4122,不会出警告
  • 原生javascript实现放大镜效果
  • 【数据中台】开源项目(1)-LarkMidTable
  • Windows安装mysql8.0
  • 超好玩C++控制台打飞机小游戏,附源码