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

MySQL中的锁

共享锁

共享锁也成为读锁,针对同一份数据,多个事务的读操作可以同时进行而不会互相影响,相互不阻塞的。

  • 通过下面命令加共享锁
SELECT...LOCK IN SHARE MODE
#或
SELECT...FOR SHARE;#(8.0新增语法)

排他锁

排他锁也叫写锁,当一个事务对一份数据执行写入,即加上排他锁后,其他事务对同一份数据进行读写操作会阻塞,直到前一个事务提交。

  • 通过下面的命令加排他锁
SELECT ... FOR UPDATE;
  • DELETEUPDATEINSERT等操作也相当于加排他锁

共享锁和排他锁是否会发生阻塞如下图所示:

共享锁排他锁
共享锁不阻塞阻塞
排他锁阻塞阻塞

行级锁

行级锁是锁住行,粒度小,性能较高,但是行级锁只在存储引擎层实现,行级锁分为3种,记录锁、间隙锁和临键锁。

假如下面的一个表test_lock:

idab
000
444
888
161616
323232
  • id是主键索引
  • a是普通索引
  • b是普通列

记录锁 (Record Locks)

记录锁是仅仅锁住一条记录,锁的粒度最小。

什么时候会加记录锁?

当用唯一索引进行等职查询时,且查询的记录是存在的时候,会加记录锁。

会话1会话2会话3
begin;select * from test_lock where id = 16 for update;
update test_lock set a = 100 where id = 16;(阻塞)
insert into test_lock value(9, 9, 9);(正常)
  • 会话1对id=16记录加了行锁
  • 会话2阻塞,无法对这条记录进行修改操作
  • 会话3正常插入

间隙锁(Gap Locks)

"幻读"的问题,事务期间其他事务添加一条数据,再次读取突然多出一条记录。为了解决这样的问题,是不是可以对一段区间的数据加锁,加上锁以后,其他事务添加数据时必须阻塞。像这样的锁就叫做间隙锁,即锁定一个区间,左开右开。

什么情况会加 间隙锁

  • 在用唯一索引进行等值查询时,当查询记录不存在时,会加间隙锁。
select * from test_lock where id = 10 for update;

id=10位于8到16区间,由于10这条记录不存在,所以加的间隙锁,锁定(8, 16)的区间。

  • 唯一锁引使用范围查询的时候,会加间歇锁。
select * from test_lock where id <10 and id> 8 for update;

id <10 and id> 8是一个范围查询,会锁定范围(8,16)

  • 普通索引等值查询时,如果记录存在,会额外添加一个间隙锁。
select * from test_lock where a = 8 for update;

由于a=8记录存在,会对范围(4,8]添加临键锁,这个后面会提到,同时额外向下遍历到第一个不符合条件的值才能停止,因此间隙锁的范围是(8,16)

  • 通索引等值查询时,如果记录不存在,会加一个间隙锁。
select * from test_lock where a = 10 for update;

此种情况锁定的范围为(8,16)

临键锁(Next-Key Locks)

如果想要同时集合上面的记录锁和间隙锁,也就是既想锁住某条记录,又想阻止其他事务在该记录前边的间隙插入新记录,所以InnoDB就提出了临键锁(Next-Key Locks),默认锁定的范围是左开右闭。InnoDB存储引擎默认的锁单位就是临键锁(Next-Key Locks),怎么理解呢?

也就是锁加锁都是按照临键锁加锁,但是会根据一定的规律退化为记录锁和间隙锁。具体规律如下:

唯一索引等值查询:

  • 当查询的记录是存在的,临键锁会退化成「记录锁」。
  • 当查询的记录是不存在的,临键锁 会退化成「间隙锁」。

非唯一索引等值查询:

  • 当查询的记录存在时,除了会加 临键锁外,还额外加间隙锁,也就是会加两把锁。
  • 当查询的记录不存在时,只会加 临键锁,然后会退化为间隙锁,也就是只会加一把锁。

InnoDB存储引擎中,如果一个表查询或者更新没有走索引,这时候还会创建行级锁吗? 答案是不会,这时候会升级为表级锁。

页级锁

页级锁是 MySQL 中锁定粒度介于行级锁和表级锁中间的一种锁。表级锁速度快,但冲突多,行级冲突少,但速度慢。因此,采取了折衷的页级锁,一次锁定相邻的一组记录。BDB (BerkeleyDB)存储引擎 支持页级锁。

特点

  • 开销和加锁时间界于表锁和行锁之间
  • 会出现死锁
  • 锁定粒度界于表锁和行锁之间,并发度一般

表级锁

表锁会锁定整张表,它是MySQL中最基本的锁策略,并不依赖于存储引擎,表锁是开销最小的策略。因为表级锁一次会将整个表锁定,所以可以很好的避免死锁问题。但是表锁的并发度很差,那表锁都有哪几种呢?

表级别的S锁、X锁

  • LOCK TABLES t READ :InnoDB存储引擎会对表 t 加表级别的 S锁 。
  • LOCK TABLES t WRITE:InnoDB存储引擎会对表 t 加表级别的 X锁 。

意向锁

意向锁也是一种表锁,表示某个事务正在锁定一行或者将要锁定一行,表明一个意图。它不与行级锁冲突。那它究竟有啥作用?

意向锁是在当事务加表锁时发挥作用。比如一个事务想要对表加排他锁,如果没有意向锁的话,那么该事务在加锁前需要判断当前表的每一行是否已经加了锁,如果表很大,遍历每行进行判断需要耗费大量的时间。如果使用意向锁的话,那么加表锁前,只需要判断当前表是否有意向锁即可,这样加快了对表锁的处理速度。

意向锁分为两种:

  • 意向共享锁(intention shared lock, IS):事务有意向对表中的某些行加共享锁(S锁)
  • 意向排他锁(intention exclusive lock, IX):事务有意向对表中的某些行加排他锁(X锁)

自增锁(AUTO-INC LOCK)

我们都知道在使用创建表的时候有自增主键AUTO_INCREMENT属性,那它是怎么实现自增的呢?

AUTO-INC锁是当向使用含有AUTO_INCREMENT列的表中插入数据时需要获取的一种特殊的表级锁,在执行插入语句时就在表级别加一个AUTO-INC锁,然后为每条待插入记录的AUTO_INCREMENT修饰的列分配递增的值,在该语句执行结束后,再把AUTO-INC锁释放掉。

元数据锁(MDL锁)

元数据锁可以用来保证读写的正确性。比如,如果一个查询正在遍历一个表中的数据而执行期间另一个线程对这个 表结构做变更 ,增加了一列,那么查询线程拿到的结果跟表结构对不上,肯定是不行的。

  • 当对一个表做增删改查操作的时候,加 MDL读锁;
  • 当要对表做结构变更操作的时候,加 MDL 写锁。

MDL读锁和读锁之间可以共享兼容,读锁和写锁之间不兼容,会互相阻塞。

全局锁

全局锁就是对 整个数据库实例 加锁。当你需要让整个库处于 只读状态 的时候,可以使用这个命令,之后 其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结 构等)和更新类事务的提交语句。

全局锁的典型使用场是做全库逻辑备份。

## 全局锁命令
flush tables with read lock

悲观锁

悲观锁是总以最坏的情况假设,比如操作一条数据,总认为也有其他线程要拿这条数据,那就给这条数据上排他锁,让其他事务或者线程阻塞,类似于Java中 synchronized 和 ReentrantLock 等独占锁的思想。

适用场景:

悲观锁适写操作多的场景,因为写的操作具有 排它性 。采用悲观锁的方式,可以在数据库层 面阻止其他事务对该数据的操作权限,防止读 - 写和写 - 写的冲突。

实现思路:

以秒杀商品为例,为了防止超卖,需要加锁。

#第1步: for update 方式查出商品库存
select quantity from items where id 1001 for update;
#第2步:如果库存大于0,则根据商品信息生产订单
insert into orders (item_id)values(1001);
#第3步:修改商品的库存,um表示购买数量
update items set quantity quantity-num where id 1001;

select····for update是MySQL中悲观锁。此时在items表中,id为1001的那条数据就被我们锁定了,其他的要执行select quantity from items where id=1001 for update;语句的事务必须等本次事务提交之后才能执行。这样我们可以保证每次事务能拿到最新的库存数量,从而不会超卖,但是这样的性能很差。

乐观锁

乐观锁认为一个事务发生并发的概率很小,就不加通过数据库加锁实现,因为加锁性能比较差,而是通过程序实现,那如何数据没有被其他事务修改了呢?会在更新数据的时候判断数据的版本或者时间戳是否发生变化。

实现思路:

版本号机制实现乐观锁

  • 数据表中新增一个version字段
  • 更新前读取出version字段
  • 进行业务逻辑操作,更新数据, UPDATE ... SET version=version+1 WHERE version=version,版本+1
  • 如果有其他线程更新了数据,那么上面的修改不成功,返回值为0,表示已经被人更新了,我们可以根据0去做业务操作

时间戳机制实现乐观锁

时间戳和版本号机制一样,也是在更新提交的时候,将当前数据的时间戳和更新之前取得的时间戳进行 比较,如果两者一致则更新成功,否则就是版本冲突。

适用场景:

乐观锁适合读操作多的场景,相对来说写的操作比较少。它的优点在于 程序实现 ,不存在死锁问题。

相关文章:

MySQL中的锁

共享锁 共享锁也成为读锁&#xff0c;针对同一份数据&#xff0c;多个事务的读操作可以同时进行而不会互相影响&#xff0c;相互不阻塞的。 通过下面命令加共享锁 SELECT...LOCK IN SHARE MODE #或 SELECT...FOR SHARE;#(8.0新增语法)排他锁 排他锁也叫写锁&#xff0c;当一…...

WebView自定义进度条、加载动画,拿走直接用~

年前有个小需求&#xff0c;要对有些域名的H5进行加载流程优化&#xff0c;通过展示H5加载动画来安抚用户焦躁的心情&#xff0c;以提高用户体验。虽然不能理解加个动画咋就优化了用户体验&#xff0c;但需求还是得做的。想着这是个基础的小功能&#xff0c;独立性比较好&#…...

内存数据库Apache Derby、H2

概述 传统关系型数据库涉及大量的工作&#xff0c;如果想在Java应用程序里使用MySQL数据库&#xff0c;至少需要如下步骤&#xff1a; 安装&#xff08;可选&#xff1a;配置用户名密码&#xff09;建表&#xff08;要么从命令行进入&#xff0c;要么安装一个可视化工具&…...

麻省理工出版 | 2023年最新深度学习综述手册

UCL Simon Prince的新书&#xff1a;《Understanding Deep Learning》 &#xff0c;在2023年2月6日由MIT Press出版。他之前写过很受欢迎的《Computer Vision: Models, Learning, and Inference》。 关于这本最新的深度学习手册&#xff0c;作者这样介绍它&#xff1a; 正如书…...

vi命令详解

VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Oct 13 2020 16:04:38) 用法: vim [参数] [文件 …] 编辑指定的文件 或: vim [参数] - 从标准输入(stdin)读取文本 或: vim [参数] -t tag 编辑 tag 定义处的文件 或: vim [参数] -q [errorfile] 编辑第一个出错处的文件 参数:…...

抖音的外卖行业入局,为中小外卖企业创业者的机会给了哪些机会?

一则关于抖音进入外卖市场的消息&#xff0c;让美团“非常受伤”。 2月8日&#xff0c;美团(03690.HK&#xff09;盘中跌幅超9%。截至收盘&#xff0c;美团报收153.1港元&#xff0c;跌幅6.48%。美团大幅下跌的根源就是前一天关于抖音外卖进展的消息传闻。 2月7日&#xff0c…...

供应PEG试剂AC-PEG-COOH,Acrylate-PEG-Acid,丙烯酸酯-PEG-羧基

英文名称&#xff1a;AC-PEG-COOH&#xff0c;Acrylate-PEG-Acid 中文名称&#xff1a;丙烯酸酯-聚乙二醇-羧基 丙烯酸酯-PEG-COOH是一种含有丙烯酸酯和羧酸的线性杂双功能PEG试剂。它是一种有用的带有PEG间隔基的交联剂。丙烯酸酯可与紫外光或自由基引发剂聚合。丙烯酸酯-PE…...

java二叉排序树

1.先看一个需求 给你一个数列 (7, 3, 10, 12, 5, 1, 9)&#xff0c;要求能够高效的完成对数据的查询和添加 2.解决方案分析 使用数组 数组未排序&#xff0c; 优点&#xff1a;直接在数组尾添加&#xff0c;速度快。 缺点&#xff1a;查找速度慢. [示意图] 数组排序&#xf…...

聊一聊 gRPC 的四种通信模式

温馨提示&#xff1a;本文需要结合上一篇 gRPC 文章一起食用&#xff0c;否则可能看不懂。 前面一篇文章松哥和大家聊了 gRPC 的基本用法&#xff0c;今天我们再来稍微深入一点点&#xff0c;来看下 gRPC 中四种不同的通信模式。 gRPC 中四种不同的通信模式分别是&#xff1a;…...

科技云报道:开源真的香,风险知多少?

科技云报道原创。 过去几年&#xff0c;开源界一片火热&#xff0c;开源软件技术已全面进军操作系统、云原生、人工智能、大数据、半导体、物联网等行业领域。 数据显示&#xff0c;我国超九成企业在使用或正计划使用开源技术。 与此同时&#xff0c;全球各大开源组织相继兴…...

国产化适配迁移记录

国产化适配迁移记录 本项目基于RuoYi-Vue的框架进行迁移。目前已完成覆盖测试暂无其他问题。 国产化环境 名称版本达梦数据库DmJdbcDriver18 8.1.2.144通用mapper – tk.mybatismapper-spring-boot-starter 4.2.5<!-- 达梦数据库--><dependency><groupId>…...

又一国产开源项目走向世界,百度RPC框架Apache bRPC正式成为ASF顶级项目

2023 年 1 月 26 日&#xff0c;Apache 软件基金会 (ASF) 官方正式宣布Apache bRPC 正式毕业&#xff0c;成为 Apache的顶级项目。 我听到这个消息是挺开心的&#xff0c;毕竟是又一款由国人主导的apche顶级项目&#xff0c;再次证明国内在开源界正在发挥越来越重要的作用。 …...

多数据库学习之GBase8s查询数据库表元信息常用SQL

多数据库学习之GBase8s查询数据库表元信息常用SQL简介常用SQL创建用户创建数据库及模式获取表元数据其他参考链接简介 背景介绍 GBase 8t是基于IBM informix源代码、编译和测试体系自主研发的交易型数据库产品。 南大通用安全数据库管理系统&#xff08;简称 GBase 8s&#xff…...

Jetpack之Lifecycle应用与源码分析

Build lifecycle-aware components that can adjust behavior based on the current lifecycle state of an activity or fragment. 上面是源于官网的定义&#xff0c;简单翻译就是说Lifecycle的作用就是基于当前的Activity或者Fragment的生命周期当前状态构建可感知生命周期的…...

Python序列类型之集合

&#x1f490;&#x1f490;&#x1f490;欢迎来到小十一的博客&#xff01;&#xff01;&#xff01; &#x1f3af;博客主页&#xff1a;&#x1f3af;程序员小十一的博客 &#x1f680;博客专栏&#xff1a;&#x1f680;Python入门基础语法 &#x1f337;欢迎关注&#xff…...

java 自定义json解析注解 复杂json解析

java 自定义json解析注解 复杂json解析 工具类 目录java 自定义json解析注解 复杂json解析 工具类1.背景2、需求-各式各样的json一、一星难度json【json对象中不分层】二、二星难度json【json对象中出现层级】三、三星难度json【json对象中存在数组】四、四星难度json【json对象…...

Vue3配置路由(vue-router)

文章目录前言一、配置路由&#xff08;vue-router&#xff09;1、安装路由2、新建页面3、创建路由配置文件4.特殊报错&#xff01;前言 紧接上篇文章&#xff0c;vue3的配置与vue2是有所差别的&#xff0c;本文就讲述了如何配置&#xff0c;如果本文对你有所帮助请三连支持博主…...

【代码随想录二刷】Day9-字符串-C++

代码随想录二刷Day9 今日任务 28.找出字符串中第一个匹配项的下标 459.重复的子字符串 字符串总结 双指针总结 语言&#xff1a;C KMP 链接&#xff1a;https://programmercarl.com/0459.重复的子字符串.html#kmp 用处&#xff1a;当出现字符串不匹配时&#xff0c;可以利…...

google colab上如何下载bert相关模型

首先要知道模型的地址 tensorflow版本的模型&#xff1a; https://storage.googleapis.com/bert_models/2018_10_18/cased_L-12_H-768_A-12.zip https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip pytorch版本的模型 ‘bert-base-cased’: …...

Vue2.0页面缓存机制联合页面标签的交互(keep-alive + router)

预期效果&#xff1a;&#xff08;借助iview-ui的在线体验页面示意一下&#xff09; 项目中只有一部分页面需要缓存&#xff0c;且存在多级路由的页面。每打开一个菜单&#xff0c;就会新增一个 Tab标签&#xff0c;只要 Tab标签不关闭&#xff0c;对应的页面就会被缓存&#x…...

C++STL剖析(四)—— stack和queue的概念和使用

文章目录1. stack的介绍2. stack的构造3. stack的使用&#x1f351; push&#x1f351; top&#x1f351; pop&#x1f351; empty&#x1f351; size&#x1f351; swap&#x1f351; emplace4. queue的介绍5. queue的构造6. queue的使用&#x1f351; push&#x1f351; size…...

流浪地球 | 建筑人是如何看待小破球里的黑科技的?

大家好&#xff0c;这里是建模助手。 想问问大家今年贺岁档&#xff0c;都跟上没有&#xff0c;今天请允许我蹭一下热点表达一下作为一个科幻迷的爱国之情。 抛开大刘的想象力、各种硬核科技&以及大国情怀不提&#xff0c;破球2中的传承还是让小编很受感动&#xff0c;无…...

软中断在bottom-half中调用

https://www.bilibili.com/read/cv20785285/简介软中断可以在两个位置得到机会执行&#xff1a;硬中断返回前 irq_exit中断下半部 Bottom-half Enable后情景分析情景1spin_unlock_bh__raw_spin_unlock_bh__local_bh_enable_ip 打开Bottom-half&#xff0c;并让softirq有机会…...

GEE遥感云大数据在林业中的应用

近年来遥感技术得到了突飞猛进的发展&#xff0c;航天、航空、临近空间等多遥感平台不断增加&#xff0c;数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量猛增&#xff0c;遥感数据已经越来越具有大数据特征。遥感大数据的出现为相关研究提供了前所未有的机遇&#xf…...

Apollo架构篇 - 客户端架构

前言 本文基于 Apollo 1.8.0 版本展开分析。 客户端 使用 Apollo 支持 API 方式和 Spring 整合两种方式。 API 方式 API 方式是最简单、高效使用使用 Apollo 配置的方式&#xff0c;不依赖 Spring 框架即可使用。 获取命名空间的配置 // 1、获取默认的命名空间的配置 C…...

JVM调优最全面的成长 :参数详解+垃圾算法+示例展示+类文件到源码+面试问题

目录1.优秀的Java开发者1.1 什么是Java&#xff1f;1.2 编程语言1.3 计算机[硬件]能够懂的语言1.3.1 计算机发展史1.3.2 计算机体系结构1.3.3 计算机处理数据过程1.3.4 机器语言1.3.5 不同厂商的CPU1.3.6 操作系统1.3.7 汇编语言1.3.8 高级语言1.3.9 编译型和解释型1.3.9.1 编译…...

linux驱动常用函数

以下为一些常见用户态函数在内核中的替代&#xff0c;包括头文件和函数声明&#xff1a;1、动态申请内存&#xff1a;linux/vmalloc.hvoid *vmalloc(unsigned long size);void vfree(const void *addr);2、字符串操作&#xff1a;linux/string.hvoid * memset(void *,int,__ker…...

Flowable进阶学习(九)数据对象DataObject、租户Tenant、接收任务ReceiveTask

文章目录一、数据对象DataObject二、租户 Tenant三、接收任务 ReceiveTask案例一、数据对象DataObject DataObject可以⽤来定义⼀些流程的全局属性。 绘制流程图&#xff0c;并配置数据对象&#xff08;不需要选择任意节点&#xff09; 2. 编码与测试 /*** 部署流程*/ Test…...

C语言实现五子棋(n子棋)

五子棋的历史背景&#xff1a; 五子棋起源于中国&#xff0c;是全国智力运动会竞技项目之一&#xff0c;是一种两人对弈的纯策略型棋类游戏。双方分别使用黑白两色的棋子&#xff0c;下在棋盘直线与横线的交叉点上&#xff0c;先形成五子连珠者获胜。五子棋容易上手&#xff0c…...

OpenStack云平台搭建(2) | 安装Keystone

目录 1、登录数据库配置 2、数据库导入Keystone表 3、配置http服务 4、创建域、用户 5、创建脚本 Keystone&#xff08;OpenStack Identity Service&#xff09;是 OpenStack 框架中负责管理身份验证、服务访问规则和服务令牌功能的组件。下面我们进行Keystone的安装部署 1…...

青岛市建设局网站停工/广州网络推广培训

[Warning] incompatible implicit declaration of built-in function ‘memset’ 原因是memset第一个参数是void * 类型&#xff0c;我用的是char类型&#xff0c;存在隐式声明 第一想法是强制类型转换&#xff0c;memset((void*)xx, 0, sizeof(xx)); 还是不行&#xff0c;依然…...

destoon 网站搬家/公司网络营销实施计划

[冰多多]Alpha项目展示 冰多多项目: 语音coding 助手, alpha阶段目标: 语音辅助输入 一. 团队成员的简介和个人博客地址 成员角色个人博客地址卓培锦PM, 后端开发https://www.cnblogs.com/butub/牛雅哲后端http://www.cnblogs.com/swainz/韩笑冰前端后端对接http://www.cnblogs…...

做家居网站/百度一下首页百度一下

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼我们知道&#xff0c;公历的平年是365天&#xff0c;闰年是366天。置闰的方法是能被4整除的年份在2月加一天&#xff0c;但能被100整除的不闰&#xff0c;能被400整除的又闰。因此&#xff0c;像1600、2000、2400年都是闰年&#x…...

做网络销售怎么建立网站/搜索大全引擎入口

#include<stdio.h> void zy1() {int a;printf("请输入题目序号&#xff08;1-3&#xff09;&#xff1a;\n实验1-1&#xff1a;求最大值\n要求由键盘输入两个整数a和b&#xff0c;程序输出其中较大的数。\n实验1-2&#xff1a;求m到n之和\n要求程序计算并输出m~n&am…...

建设银行网站网址/百度seo关键词排名查询工具

文章目录一、核心组件1.1 SecurityContextHolder类1.1.1 概念1.1.2 存储策略1.1.3 源码1.2 SecurityContext接口1.3 Authentication接口1.4 GrantedAuthority接口1.5 UserDetails接口1.6 UserDetailsService接口1.7 AuthenticationManager接口1.8 DaoAuthenticationProvider二、…...

免费做四年级题的网站/百度地图导航2022最新版

环境变量操作命令1、修改环境变量2、新建环境变量3、删除环境变量1、修改环境变量 环境变量的操作涉及到两个命令&#xff1a; setenv 和 saveenv 命令描述setenv用于设置或者修改环境变量的值saveenv用于保存修改后的环境变量 一般环境变量是存放在外部 flash 中的,uboot 启…...