select...for update锁详解

news2025/2/25 22:09:07

select…for update锁详解

select…for update的作用就是:如果A事务中执行了select…for update,那么在其提交或回滚事务之前,B,C,D…事务是无法操作(写)A事务select…for update所命中的数据的!

前提条件

MySQL中通过select…for update实现悲观锁

select…for update仅适用于InnoDB,且查询需命中,事务需在手动提交下才能生效
MySQL事务隔离级别的不同会影响到上锁策略,本文内容基于MySQL默认隔离级别可重复读(REPEATABLE-READ)

-- 查询当前事务隔离级别
-- MySQL5.7.20版本之前
SHOW VARIABLES LIKE 'tx_isolation';
-- MySQL5.7.20版本及之后
SHOW VARIABLES LIKE 'transaction_isolation';
-- 都可使用
SELECT @@transaction_isolation;

-- 设置事务隔离级别为REPEATABLE-READ;session范围为当前会话,global全局范围
-- 方式1:
-- SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL 隔离级别;
-- 其中,隔离级别格式:
-- > READ UNCOMMITTED
-- > READ COMMITTED
-- > REPEATABLE READ
-- > SERIALIZABLE
set session transaction isolation level repeatable read;
-- 或
set global transaction isolation level repeatable read;

-- 方式2:
-- SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔离级别'
-- 其中,隔离级别格式:
-- > READ-UNCOMMITTED
-- > READ-COMMITTED
-- > REPEATABLE-READ
-- > SERIALIZABLE
SET SESSION TRANSACTION_ISOLATION = 'REPEATABLE-READ';
-- 或
SET GLOBAL TRANSACTION_ISOLATION = 'REPEATABLE-READ';

行锁,表锁

行锁:锁的是数据行,一条或多条数据
表锁:锁的是表,将整张表的全部数据锁住

select…for update锁的是行还是表,可以通过相关查询判断:

-- 查看正在执行的事务列表
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
-- 查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
-- 查看等待锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
-- 查询是否锁表
SHOW OPEN TABLES WHERE In_use > 0;
-- 查询进程
SHOW PROCESSLIST;
-- 查询死锁信息
SHOW ENGINE INNODB STATUS;
-- 杀死进程
KILL <thread_id>;
-- 设置超时时间防止死锁
SET innodb_lock_wait_timeout = <timeout_value>;

相关表字段分析:

innodb_trx表:
trx_id:事务ID。
trx_state:事务状态,有以下几种状态:RUNNING、LOCK WAIT、ROLLING BACK 和 COMMITTING。
trx_started:事务开始时间。
trx_requested_lock_id:事务当前正在等待锁的标识,可以和 INNODB_LOCKS 表 JOIN 以得到更多详细信息。
trx_wait_started:事务开始等待的时间。
trx_weight:事务的权重。
trx_mysql_thread_id:事务线程 ID,可以和 PROCESSLIST 表 JOIN。
trx_query:事务正在执行的 SQL 语句。
trx_operation_state:事务当前操作状态。
trx_tables_in_use:当前事务执行的 SQL 中使用的表的个数。
trx_tables_locked:当前执行 SQL 的行锁数量。
trx_lock_structs:事务保留的锁数量。
trx_lock_memory_bytes:事务锁住的内存大小,单位为 BYTES。
trx_rows_locked:事务锁住的记录数。包含标记为 DELETED,并且已经保存到磁盘但对事务不可见的行。
trx_rows_modified:事务更改的行数。
trx_concurrency_tickets:事务并发票数。
trx_isolation_level:当前事务的隔离级别。
trx_unique_checks:是否打开唯一性检查的标识。
trx_foreign_key_checks:是否打开外键检查的标识。
trx_last_foreign_key_error:最后一次的外键错误信息。
trx_adaptive_hash_latched:自适应散列索引是否被当前事务锁住的标识。
trx_adaptive_hash_timeout:是否立刻放弃为自适应散列索引搜索 LATCH 的标识。
 
innodb_locks表:
lock_id:锁 ID。
lock_trx_id:拥有锁的事务 ID。可以和 INNODB_TRX 表 JOIN 得到事务的详细信息。
lock_mode:锁的模式。有如下锁类型:行级锁包括:S、X、IS、IX,分别代表:共享锁、排它锁、意向共享锁、意向排它锁。表级锁包括:S_GAP、X_GAP、IS_GAP、IX_GAP 和 AUTO_INC,分别代表共享间隙锁、排它间隙锁、意向共享间隙锁、意向排它间隙锁和自动递增锁。
lock_type:锁的类型。RECORD 代表行级锁,TABLE 代表表级锁。
lock_table:被锁定的或者包含锁定记录的表的名称。
lock_index:当 LOCK_TYPE=’RECORD’ 时,表示索引的名称;否则为 NULL。
lock_space:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的表空间 ID;否则为 NULL。
lock_page:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的页号;否则为 NULL。
lock_rec:当 LOCK_TYPE=’RECORD’ 时,表示一堆页面中锁定行的数量,亦即被锁定的记录号;否则为 NULL。
lock_data:当 LOCK_TYPE=’RECORD’ 时,表示锁定行的主键;否则为NULL。
 
innodb_lock_waits表:
requesting_trx_id:请求事务的 ID。
requested_lock_id:事务所等待的锁定的 ID。可以和 INNODB_LOCKS 表 JOIN。
blocking_trx_id:阻塞事务的 ID。
blocking_lock_id:某一事务的锁的 ID,该事务阻塞了另一事务的运行。可以和 INNODB_LOCKS 表 JOIN

查询条件影响锁规则

where条件:

条件说明行锁/表锁
主键主键字段作为查询条件行锁
索引索引字段作为查询条件行锁
普通字段普通字段作为查询条件表锁
-- id字段为主键  
-- age字段创建B-TREE索引
CREATE TABLE stu (
 id INT ( 11 ) NOT NULL AUTO_INCREMENT,
 name VARCHAR ( 255 ) DEFAULT NULL,
 age INT ( 11 ) DEFAULT NULL,
 code VARCHAR ( 255 ) DEFAULT NULL,
 PRIMARY KEY ( id ),
 KEY idx_age ( age ) USING BTREE 
) ENGINE = INNODB AUTO_INCREMENT = 1570068 DEFAULT CHARSET = utf8;

image.png

测试1

图1
image.png

图2
image.png

图3
image.png

分析:

  • 图1:A事务执行select * from stu where id = 1001 for update; 以主键字段作为查询条件
  • 图2:B事务执行update stu set name = ‘zs’ where id = 1001; 对id为1001的数据(事务A查询出的数据)进行修改,阻塞等待,最后长时间拿不到锁报错
  • 图3:B事务执行update stu set name = ‘ls’ where id = 1009; 对其他数据进行修改,修改成功

总结:
以主键字段作为条件上锁,锁的是行,是表中查询命中的数据

测试2

图1
image.png

图2
image.png

图3
image.png

分析:

  • 图1:A事务执行select * from stu where age = 22 for update; 以索引字段作为查询条件
  • 图2:B事务执行update stu set name = ‘ls’ where id = 1009; 对id为1009的数据(事务A查询出的数据)进行修改,阻塞等待,最后长时间拿不到锁报错
  • 图3:B事务执行update stu set name = ‘张三’ where id = 1001; 对其他数据进行修改,修改成功

总结:
以索引字段作为条件上锁,锁的是行,是表中查询命中的数据

测试3

图1
image.png

图2
image.png

图3
image.png

分析:

  • 图1:A事务执行select * from stu where code = ‘JS1001’ for update; 以普通字段作为查询条件
  • 图2:B事务执行update stu set name = ‘章山’ where id = 1001; 对id为1001的数据(事务A查询出的数据)进行修改,阻塞等待,最后长时间拿不到锁报错
  • 图3:B事务执行update stu set name = ‘Lisa’ where id = 1009; 对其他数据进行修改,阻塞等待,最后长时间拿不到锁报错

总结:
以普通字段作为条件上锁,锁的是表,该表的全部数据

组合条件

and组合条件
条件行锁/表锁
主键 and 索引行锁
主键 and 普通字段行锁
索引 and 普通字段行锁

or组合条件
条件行锁/表锁
主键 or 索引行锁
主键 or 普通字段表锁
索引 or 普通字段表锁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1383067.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

游戏找不到emp.dll,无法运行的5种解决方法

游戏在运行过程中提示找不到emp.dll文件&#xff0c;这一现象的原因可能涉及到多个层面。首先&#xff0c;emp.dll是一个动态链接库文件&#xff0c;对于特定的游戏运行至关重要&#xff0c;它可能包含了游戏运行所必需的函数、资源或其他关键信息。当系统在加载游戏时无法找到…

【AI】Pytorch 系列:预训练模型使用

1. 模型下载 import re import os import glob import torch from torch.hub import download_url_to_file from torch.hub import urlparse import torchvision.models as modelsdef download_

k8s云原生环境搭建笔记——第二篇

目录 1、使用普通方式安装prometheus和grafana1.1、安装kube-state-metrics容器1.1.1、下载并修改yaml文件1.1.2、导入kube-state-metrics镜像1.1.3、执行yaml文件目录 1.2、安装node-exploer1.2.1、创建名称空间prometheus1.2.2、执行yaml 1.3、安装prometheus1.3.1、创建集群…

【洛谷千题详解】P1980 [NOIP2013 普及组] 计数问题

#include<bits/stdc.h> using namespace std; int main() {int n,x,ans0;cin>>n>>x;for(int i1;i<n;i){int numberi;while(number){int anumber%10;number/10;if(ax) ans;}}cout<<ans<<endl;return 0; }

ssm基于java的自助医疗服务系统的设计与实现+jsp论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本自助医疗服务系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

代码随想录 Leetcode142. 环形链表 II

题目&#xff1a; 代码(首刷看解析 2024年1月13日&#xff09;&#xff1a; class Solution { public:ListNode *detectCycle(ListNode *head) {if (head nullptr) return nullptr;ListNode* fast head;ListNode* slow head;while (true) {if(fast->next nullptr || fa…

DICE模型的原理与推导、碳循环与气候变化、政策评估、不确定性分析与代码分析

目录 专题一&#xff1a;DICE模型的原理与推导 专题二&#xff1a;碳循环与气候变化 专题三&#xff1a;政策评估 专题四&#xff1a;不确定性分析与代码分析 更多应用 随着温室气体排放量的增大和温室效应的增强&#xff0c;全球气候变化问题受到日益的关注。我国政府庄严…

函数栈桢的创建和销毁

函数栈桢的创建和销毁 一、解决的问题二、认识常用的寄存器及其指令操作三、函数栈桢解析三、回答问题 一、解决的问题 1.局部变量是怎么创建的&#xff1f;  2.为什么局部变量的值是随机值&#xff1f;  3.函数是怎么传参的&#xff1f;传参的顺序是怎样的&#xff1f;  4.…

漏洞修复整理

一、Geoserver Apache HTTP/2拒绝服务漏洞&#xff08;CVE-2023-44487&#xff09;、Eclipse Jetty 资源管理错误漏洞(CVE-2023-26048)、Eclipse Jetty 信息泄露漏洞(CVE-2023-26049) 受影响版本&#xff1a;9.4.53以下版本 处理方式&#xff1a;原地升级 &#xff08; jdk版本…

Vue3 如何使用移动端调试工具vConsole

1、安装 pnpm i vconsole2、在src/utils下新建vconsole.ts&#xff0c;写入以下代码 // 这是移动端控制台调试工具&#xff0c;需要调试就打开,不用就注释 import vConsole from vconsole const vconsole new vConsole()3、src/main.ts 引入&#xff0c;需要调试就打开,&…

熊猫电竞赏金电竞系统源码 APP+H5双端 附搭建教程 支持运营级搭建

简介: 熊猫电竞赏金电竞系统源码 APP+H5双端 附搭建教程 支持运营级搭建 可搭建!运营级!首次公开! 赏金赛源码,用户通过平台打比赛,赢了获得奖金奖励, 金币赛、赏金赛、vip赛等种赛事 可开王者荣耀、和平精英比赛 支持1v1、单排、双排组、战队排等多种比赛模式 …

手写springBoot启动器

提示&#xff1a;springboot原理&#xff0c;手写springboot启动器&#xff0c;手写模拟SpringBoot启动过程、手写模拟SpringBoot自动配置功能 文章目录 前言一、本文内容1、手写模拟SpringBoot启动过程2、手写模拟SpringBoot自动配置功能 二、项目总体介绍三、代码实现(手写模…

Adobe Illustrator 2023--AI2023中文

Adobe Illustrator 2023是一款专业的矢量图形设计软件&#xff0c;广泛应用于印刷、Web、视频和移动设备的设计制作。它提供了丰富的绘图工具、矢量图形编辑功能和灵活的排版设计工具&#xff0c;帮助用户快速高效地制作出精美的设计作品。相较于其他设计软件&#xff0c;Adobe…

分享7款前端CSS动画特效源码(附在线演示)

精选7款前端CSS动画特效源码 下面我会给出特效样式图或演示效果图 但你也可以点击在线预览查看源码的最终展示效果及下载源码资源 CSS飞行的荷包蛋 CSS荷包蛋动画 荷包蛋会向右前方加速飞行 期间还能看到周围的气流匆匆飞过 以下图片只是简单的模型没有具体的动画效果最终动画…

Python读取log文件报错“UnicodeDecodeError”

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 问题描述&#xff1a; 写了一个读取log文件的Python脚本&#xff1a; # -*- coding:utf-8 -*- import os import numpy as np …

手撕乘积(**Multiplication** **Product**): 穷举和图示(1)

手撕乘积(Multiplication & Product): 穷举和图示(1) 乘积 r ⋅ s ∑ i 1 s r r r ⋯ r ⏟ s times ∑ j 1 r s s s ⋯ s ⏟ r times r\cdot s\sum _{i1}^{s}r\underbrace {rr\cdots r} _{s{\text{ times}}}\sum _{j1}^{r}s\underbrace {ss\cdots s} _{r{\tex…

怎么把workspace的数据导入到simulink查看波形?

仿真截图&#xff1b; 示例代码&#xff1a; sampleTime 0.001; %设置采样时间 numSteps 1/sampleTimes; %设置时间矩阵长度 time sampleTime*(0:numSteps-1); %定义时间矩阵 time time; %时间矩阵转置 data sin…

【Maven】008-Maven 私服搭建与使用

【Maven】008-Maven 私服搭建与使用 文章目录 【Maven】008-Maven 私服搭建与使用一、概述1、简介2、建立私服后依赖查找和下载逻辑第一步&#xff1a;请求本地仓库第二步&#xff1a;请求 Maven 私服第三步&#xff1a;请求外部远程仓库&#xff08;远程中央仓库等&#xff09…

SOMEIP学习总结

SOMEIP学习总结&#xff08;包含VSOMEIP库&#xff09; 一.基本概念 1.SOMEIP支持TCP和UDP两种传输方式 ​ 其中&#xff0c;SOMEIP-SD的消息都是通过UDP发送的 2.SOMEIP支持如下中间件特性&#xff1a; Serialization – transforming into and from on-wire representati…

深入解析JavaScript中构造函数和new操作符

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》 ​ ​ 目录 ✨ 前言 ✨ 正文 第一节:构造函数 第二节:new操作符 第三节:实例与原型 ✨ 结语 ✨ 前言…