select...for update锁详解

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 普通字段表锁

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

php时间函数date()、getdate()、time()

目录 1. 时区修改 2. date() 3. getdate() 4. time() 1. 时区修改 位于东八区&#xff0c;修改php.ini 。date.timezone Asia/Shanghai 2. date() 获取时间函数 <?php header("Content-Type: text/html; charsetutf-8");$d date(H:i:s);//小时H&#xf…

linux驱动(五):framebuffer

本文主要探讨210的framebuffer驱动知识。 frameBuffer 用户态进程直接调用显卡写屏,framebuffer接口是给用户态进程用于写屏 framebuffer设备文件为fbx 清屏:dd if/dev/zero of/dev/fbx 清屏&#xff1a;$ dd if/dev/zero of/dev/fb0 bs1024 …

2023 IoTDB Summit:天谋科技高级开发工程师苏宇荣《汇其流:如何用 IoTDB 流处理框架玩转端边云融合》...

12 月 3 日&#xff0c;2023 IoTDB 用户大会在北京成功举行&#xff0c;收获强烈反响。本次峰会汇集了超 20 位大咖嘉宾带来工业互联网行业、技术、应用方向的精彩议题&#xff0c;多位学术泰斗、企业代表、开发者&#xff0c;深度分享了工业物联网时序数据库 IoTDB 的技术创新…

一键调整播放倍速,调整播放倍速的软件

你是否曾因为长时间的视频而感到厌烦&#xff1f;或者因为视频播放得太快而错过了一些重要内容&#xff1f;现在&#xff0c;有了我们的【媒体梦工厂】&#xff0c;这些问题都将得到完美解决。不论你是想快速浏览长视频&#xff0c;还是想让视频慢下来以便更好地学习或欣赏&…

spring-mvc(1):Hello World

虽然目前大多数都是使用springboot来开发java程序&#xff0c;或者使用其来为其他端提供接口&#xff0c;而为其他端提供接口&#xff0c;这些功能都是依靠springmvc实现的&#xff0c;所以有必要学习一下spring-mvc&#xff0c;这样才能更好的学习springboot。 一&#xff0c…

C++力扣题目236--二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是它自己的…

代码随想录 Leetcode349. 两个数组的交集

题目&#xff1a; 代码(首刷看解析 2024年1月14日&#xff09;&#xff1a; class Solution { public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int> a;unordered_set<int> res;for(int i 0…

每日一题——LeetCode1189.气球的最大数量

方法一 个人方法&#xff1a; 统计text字符串中b、a、l、o、n 这几个字符出现的次数 l和n需要两个才能拼成一个balloon&#xff0c;所以碰到l和o加1&#xff0c;其他字符加2 最后求出出现次数最少的那个字符再除以2就是能拼凑成的单词数量&#xff0c;避免出现小数要使用向下…

近红外光谱分析技术与基于深度学习的化学计量学方法

郁磊【副教授】&#xff1a;主要从事AI人工智能与大数据分析等相关研究&#xff0c;长期致力于人工智能与近红外生物医学工程等领域融合&#xff0c;主持并完成多项科研课题。著有《神经网络43个案例分析》等书籍。 // 讲座内容 1、近红外光谱基本理论、近红外光谱仪基本原理…

clickhouse join查询算法

算法对比&#xff1a; 使用方法&#xff1a; SELECT town,max(price) AS max_price,any(population) AS population FROM uk_xxx_paid JOIN uk_xxx_table ON lower(uk_price_paid.town) lower(uk_populations_table.city) GROUP BY town ORDER BY max_price DESC SETTINGS jo…

对接苹果CMS芒果影视APPV1.0(附安装教程+源码支持多端)内置采集脚本

目录 概述1. 演示效果1.1 视频演示1.2 图文演示1.2.1 首页1.2.2 专题页1.2.3 搜索1.2.4 观影 2. 支持功能3. 插件和框架4. 部署方法4.1 后端4.1.1 准备工具4.1.2创建站点4.1.3 上传后端代码到服务器4.1.4 导入数据库4.1.5 配置数据库信息4.1.6访问后台管理系统 4.2 前端4.2.1 准…

影响邮件打开率的因素有哪些?

影响邮件打开率得因素有很多&#xff0c;比如说邮件地址的有效性、邮件标题、定位人群、发送频率或者时间等因素。目前来讲&#xff0c;我们可以通过技术的手段改善邮件的到达率&#xff0c;但是邮件的打开率取决于收件人本身&#xff0c;所以发件人的发送动作如何在很大程度上…

为什么光刻要用黄光

光刻是集成电路&#xff08;IC或芯片&#xff09;制造中的重要工艺之一。简单来说&#xff0c;它是通过使用光掩膜和光刻胶在基板上复制电路图案的过程。 基板将涂覆硅二氧化层绝缘层和光刻胶。光刻胶在被紫外光照射后可以容易地用显影剂溶解&#xff0c;然后在腐蚀后&#xf…

MT1138-MT1150总结

1. 判断闰年方法 year%40&&year%400&#xff01;0||year%4000 #include<bits/stdc.h> using namespace std;int day(int year,int mouth){if(mouth1||mouth3||mouth5||mouth7||mouth8||mouth10||mouth12){return 31;}else if(mouth4||mouth6||mouth9||mouth11)…

【促销定价】背后的算法技术 2 - 数据预处理生成

【促销定价】背后的算法技术 2 - 数据预处理生成 01 数据探查02 数据清洗03 数据聚合04 数据补全05 小结参考文献 导读&#xff1a;在日常生活中&#xff0c;我们经常会遇见线上/线下商家推出各类打折、满减、赠品、新人价、优惠券、捆绑销售等促销活动。一次成功的促销对于消费…

【Linux 内核源码分析笔记】系统调用

在Linux内核中&#xff0c;系统调用是用户空间程序与内核之间的接口&#xff0c;它允许用户空间程序请求内核执行特权操作或访问受保护的内核资源。系统调用提供了一种安全可控的方式&#xff0c;使用户程序能够利用内核功能而不直接访问底层硬件。 系统调用&#xff1a; 通过…

Azure Machine Learning - 视频AI技术

Azure AI 视频索引器是构建在 Azure 媒体服务和 Azure AI 服务&#xff08;如人脸检测、翻译器、Azure AI 视觉和语音&#xff09;基础之上的一个云应用程序&#xff0c;是 Azure AI 服务的一部分。 有了 Azure 视频索引器&#xff0c;就可以使用 Azure AI 视频索引器视频和音频…

Fastadmin上传图片服务端压缩图片,实测13.45M压缩为29.91K

先前条件&#xff1a;第一步安装compose&#xff0c;已安装忽略。 先上截图看效果 一、在fastadmin的根目录里面输入命令安装think-image composer require topthink/think-image二、找到公共上传类&#xff0c;application/common/library/Upload.php&#xff0c;在最下面…

Java SE入门及基础(12)

do-while 循环 1. 语法 do { //循环操作 } while ( 循环条件 ); 2. 执行流程图 3. 案例 从控制台录入学生的成绩并计算总成绩&#xff0c;输入0 时退出 4. 代码实现 public static void main ( String [] args ) { Scanner sc new Scanner ( System . in )…

大面积光源HUD阳光倒灌实验装置太阳光模拟器

背景 1.根据现在市场上一些量产的hud的结构和原理可知&#xff0c;hud中最重要的零件之一就是凹面镜(自由曲面)&#xff0c;hud利用凹面镜放大投影的光学原理进行投影成像。当发生阳光倒灌时&#xff0c;太阳光沿着hud正常工作时成像的逆光路&#xff0c;通过挡风玻璃-凹面镜-…