【数据库事务锁的类型:读锁/写锁、悲观锁/乐观锁、表锁/页锁/行锁】
数据库事务锁的类型:读锁/写锁、悲观锁/乐观锁、表锁/页锁/行锁
- 一、读锁/写锁
- 1、锁定读
- 二、悲观锁/乐观锁
- 2.1 悲观锁
- 2.2 乐观锁
- 三、表锁/页锁/行锁
- 3.1 表级别的S锁、X锁
- 3.2 表级别的意向锁(intention lock)
一、读锁/写锁
对于数据库中并发事务的读-读场景不会引起什么问题,对于写-写、读-写或写-读这些场景可能会一起一些问题。
常见的可以分为2种锁:共享锁
(Shared Lock, s lock)和排他锁
(Exclusive Lock, x lock)。也叫读锁
(read lock)和写锁
(write lock)。
1、锁定读
- 对读取的记录加S锁:其他事务可以加读锁,要加写锁的话需要阻塞排队。
SELECT ... LOCK IN SHARE MODE;
# 或者
SELECT ... FOR SHARE. #(8.0新特性)
- 对读取的记录加X锁:其他事务加读锁和写锁都需要阻塞排队。
SELECT ... FOR UPDATE
二、悲观锁/乐观锁
从对待锁的态度上区分的话,可以分为悲观锁和乐观锁。
乐观锁
适合读操作多
的场景:优点是程序实现,不存在死锁问题
。悲观锁
适合写操作多
的场景:写操作多,使用乐观锁就不合适了。使用悲观锁,从数据库层面阻止其他事务对数据进行操作。
2.1 悲观锁
select…for update 语句执行过程中扫描过的行都会被加锁,因此在mysql中使用悲观锁,必须确定用上了索引,而不是全表扫描,否则会将整个表锁住。
SELECT ... FOR UPDATE
2.2 乐观锁
1、版本号机制
在表中设计一个版本字段:version。第一次读的时候获取当前版本值,更新的时候指定版本号(old_version_value)进行更新,只有当其他事务没有更新过时,这条语句才会更新成功。因此可以根据更新结果判断是否有其他事务修改过数据。
update ... set version=version+1
where version=old_version_value
2、时间戳机制
原理和版本号机制是一样的,只是说使用数据的更新时间来作为更新的指定条件。第一次查询得到数据的最新更新时间(update_time),更新的时候带着这个时间去进行更新,只有当其他事务没有更新过时,这条语句才会更新成功。
update ... set ...
where update_time=old_update_time
三、表锁/页锁/行锁
数据库系统需要在高并发响应
和系统性能
之间进行平衡,就产生了锁粒度
的概念。锁的粒度主要分为:表级锁、页级锁、行锁。
3.1 表级别的S锁、X锁
在对表执行SELECT、INSERT、DELETE、UPDATE这些DML语句时,Innodb不会添加表级别的S锁或X锁。而在对表执行ALTER TABLE、DROP TABLE这些DDL语句时,其他事务对这个表执行DML语句时会发生阻塞。这个过程是通过在server层使用一种称之为元数据锁(Metadata Lock)
结构来实现的。
一般情况下,不用手动使用到表级别的S锁和X锁:
LOCK TABLES t READ; # 手动加S锁
LOCK TABLES t WRITE; # 手动加X锁
3.2 表级别的意向锁(intention lock)
已经有一个表级别的S锁和X锁了,为什么还需要意向锁呢?
事务1对某行进行了修改,此时会对该行加一个行锁,同时会对该表加一个意向排他锁。此时事务2如果想对该表加一个表级别排他锁的话,发现已经有一个表级别意向排他锁了,此时就会阻塞。
而如果没有意向排他锁的话,事务2要对表加表级别的排他锁的话,数据库就需要对该表的每一页、每一行都查看是否有对应的页锁和行锁,这样太耗时了。
总结下:
- 意向锁的存在是为了协调行锁和表锁的关系,支持多粒度锁的共存。
- 意向锁是一种
不与行级锁冲突的表级锁
。
意向锁分为2种
- 意向共享锁(Intention Shared Lock, IS):
# 事务要获取某些行的S锁,必须先获取表的意向共享锁
SELECT ... FROM TABLE t ... LOCK IN SHARE MODE;
- 意向排他锁(Intention Exclusive Lock, IX):
# 事务要获取某些行的X锁,必须先获取表的意向排他锁
SELECT ... FROM TABLE t ... FOR UPDATE;
注意:意向锁之间是相互兼容的。但是意向锁和普通表级别的共享锁/排他锁不兼容,除了2个都是读的情况:即意向共享锁和表级别共享锁是兼容的。
相关文章:

【数据库事务锁的类型:读锁/写锁、悲观锁/乐观锁、表锁/页锁/行锁】
数据库事务锁的类型:读锁/写锁、悲观锁/乐观锁、表锁/页锁/行锁 一、读锁/写锁1、锁定读 二、悲观锁/乐观锁2.1 悲观锁2.2 乐观锁 三、表锁/页锁/行锁3.1 表级别的S锁、X锁3.2 表级别的意向锁(intention lock) 一、读锁/写锁 对于数据库中并…...

【Motion Builder】配置c++插件开发环境
目录 准备环境构建官方案例另行构建经验分享附录 准备环境 安装Motion Builder 2024并破解安装Qt 5.15.2 截止至2024年12月19日,Qt的在线安装器的默认页面是没有5.15.2版本的。你需要:在“选择组件”界面,选择“Archive”,点击“…...

多线程访问FFmpegFrameGrabber.start方法阻塞问题
一、背景 项目集成网络摄像头实现直播功能需要用到ffmpeg处理rtmp视频流进行web端播放 通过网上资源找到大神的springboot项目实现了rtmp视频流转为http请求进行视频中转功能,其底层利用javacv的FFmpegFrameGrabber进行拉流、推流,进而实现了视频中转。 …...
MySQL使用记录
char和varchar varchar是可变长的,实际用多少它就占多少,和char不同,char规定多少它就会占多少 varchar的长度是字符个数,不管是数字、英文还是汉字,varchar(10)都可以存10个,而不会出现因为汉字占更多的字…...
【视觉SLAM:六、视觉里程计Ⅰ:特征点法】
视觉里程计(Visual Odometry, VO)是通过处理图像序列,估计摄像头在时间上的相对位姿变化的技术。它是视觉SLAM的重要组成部分之一,主要通过提取图像中的信息(如特征点或直接像素强度)来实现相机运动估计。以…...
Python 数据结构揭秘:栈与队列
栈(Stack) 定义 栈是一种后进先出(Last In First Out, LIFO)的数据结构。它类似于一个容器,只能在一端进行插入和删除操作。栈有两个主要的操作:push(入栈)和 pop(出栈…...

常见的框架漏洞
1.Thinkphp Thinkphp5x远程命令执行及getshell 搭建靶场 cd vulhub/thinkphp/5-rce docker-compose up -d 首页 漏洞根本源于 thinkphp/library/think/Request.php 中method方法可以进行变量覆盖,通过覆盖类的核心属性filter导致rce,其攻击点较为多&…...
在C++中实现一个能够捕获弹窗、检查内容并在满足条件时点击按钮的程序;使用python的方案
在C中实现一个能够捕获弹窗、检查内容并在满足条件时点击按钮的程序是相当复杂的,因为C本身并不直接提供高级的GUI自动化功能。通常,这样的任务会使用Windows API(如User32.dll中的函数)或者一些第三方库(如UIAutomati…...

《Vue3实战教程》26:Vue3Transition
如果您有疑问,请观看视频教程《Vue3实战教程》...
【架构设计(一)】常见的Java架构模式
常见的 Java 架构模式解析 在 Java 开发领域,选择合适的架构模式对于构建高效、可维护且能满足业务需求的软件系统至关重要。本文将深入探讨几种常见的 Java架构模式,包括单体架构与微服务架构、分层架构与微服务架构的对比,以及事件驱动架构…...
自定义有序Map
package cn.ziqirj.common.utils;import lombok.Getter; import lombok.Setter;import java.util.ArrayList; import java.util.List;/*** 模拟Map集合,key不可重复,按插入顺序排序* author zhangji** param <T>*/ public class CustomOrderlyMap&…...

Jenkins(持续集成与自动化部署)
Jenkins 是一个开源软件项目,是基于Java开发的一种持续集成工具。 官网:https://www.jenkins.io/ GitLab安装使用 安装前提:内存至少需要4G 官方网站:https://about.gitlab.com/ 安装文档:https://docs.gitlab.c…...

redis7基础篇2 redis的哨兵模式2
目录 一 哨兵模式 1.1 redis的哨兵模式作用 1.2 redis的哨兵模式架构 1.3 redis的哨兵模式参数说明 二 redis的哨兵模式搭建 2.1 redis的主从复制模式 2.2 redis的sentinel配置文件 2.3 redis的实例节点和sentinel节点启动 3.3 redis的哨兵模式原理 3.3.1 redis的哨兵…...

windows终端conda activate命令行不显示环境名
问题: 始终不显示环境名 解决 首先需要配置conda的环境变量 确保conda --version能显示版本 然后对cmd进行初始化,如果用的是vscode中的终端,那需要对powershell进行初始化 Windows CMD conda init cmd.exeWindows PowerShell conda …...

SpringBoot 2.6 集成es 7.17
引言 在现代应用开发中,Elasticsearch作为一个强大的搜索引擎和分析引擎,已经成为许多项目不可或缺的一部分。Spring Boot作为Java生态中最受欢迎的微服务框架之一,其对Elasticsearch的支持自然也是开发者关注的焦点。本文将详细介绍如何在S…...
加固服务器有什么用?
为什么越来越多的企业和个人都在加固他们的服务器?加固服务器不仅可以保护数据安全,还能提升整体系统的稳定性和可靠性。下面是聚名网的一些介绍。 加固服务器的首要目的就是提高安全性。随着网络攻击手段的不断演变,黑客和恶意软件的威胁也…...

Personal APP
1、Matlab 2023b https://www.bilibili.com/opus/887246540317392920 https://blog.csdn.net/qq_25719943/article/details/138096918 https://www.jokerdown.com/22886.html 2、 3、...
探索最新的编程技术趋势:AI 编程助手和未来的编程方式
随着技术的飞速发展,编程技术领域在近年来经历了深刻的变革。从人工智能到低代码开发工具,新的技术趋势不断涌现,不仅大幅提高了开发效率,也重新定义了开发者的角色和工作方式。本篇博客将探讨几项当前最值得关注的编程技术&#…...
Android:文件管理:打开文件意图
三步走: 一、先在AndroidManifest.xml声明provider: <providerandroid:name"androidx.core.content.FileProvider"android:authorities"${applicationId}.FileProvider"android:exported"false"android:grantUriPermi…...
从纯虚类到普通类:提升C++ ABI兼容性的策略
在C编程中,纯虚类(也被称为抽象类)通常用于定义接口,而普通类则包含具体的实现。然而,在某些情况下,将纯虚类转换为普通类并提供默认实现,可以显著提升应用程序二进制接口(ABI&#…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...

JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...