深入理解Mysql——锁、事务与并发控制

高并发情况下,MYSQL的锁等待问题分析和解决方案 问题描述 在进行高并发性能调优的时候发现了如下的一个问题: 1. 在一个事务中同时包括了SELECT,UPDATE语句 2. SELECT和UPDATE涉及到的数据为同一张表中的同一记录 3. 在并发为10的情况下就会触发数据库锁等待和死锁的情况 问题分析 在问题分析之前引入几个概念 事务隔离级别 参考文章《事务的ACID特性》 共享锁(S锁) SELECT 语句时对查询行加的锁类型为共享锁。 共享锁的特性为:不允许其他事务对该记录加排他锁,但是允许加共享锁。 保持时间:可重复度级别中共享锁会保持到事务结束。 排他锁(X锁) MYSQL的默认隔离级别(可重复度)中,UPDATE,INSERT和 立即下载

下面大部分博文转自https://blog.youkuaiyun.com/lemon89/article/details/51477497

 

SQL 语句主要可以划分为以下 3 个类别。

DDL(Data Definition Languages)语句:数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象的定义。常用的语句关键字主要包括 create、drop、alter等。

DML(Data Manipulation Language)语句:数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性,常用的语句关键字主要包括 insert、delete、udpate 和select 等。(增添改查)

DCL(Data Control Language)语句:数据控制语句,用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括 grant、revoke 等。

DDL 语句:

DDL 是数据定义语言的缩写,简单来说,就是对数据库内部的对象进行创建、删除、修改的操作语言。它和 DML 语言的最大区别是 DML 只是对表内部数据的操作,而不涉及到表的定义、结构的修改,更不会涉及到其他对象。DDL 语句更多的被数据库管理员(DBA)所使用,一般的开发人员很少使用。

 

mysql并发控制——共享锁、排他锁

共享锁

共享锁也称为读锁,读锁允许多个连接可以同一时刻并发的读取同一资源,互不干扰;

排他锁

排他锁也称为写锁,一个写锁会阻塞其他的写锁或读锁,保证同一时刻只有一个连接可以写入数据,同时防止其他用户对这个数据的读写。

锁策略

锁的开销是较为昂贵的,锁策略其实就是保证了线程安全的同时获取最大的性能之间的平衡策略。

  • mysql锁策略:talbe lock(表锁)

表锁是mysql最基本的锁策略,也是开销最小的锁,它会锁定整个表;

具体情况是:若一个用户正在执行写操作,会获取排他的“写锁”,这可能会锁定整个表,阻塞其他用户的读、写操作;

若一个用户正在执行读操作,会先获取共享锁“读锁”,这个锁运行其他读锁并发的对这个表进行读取,互不干扰。只要没有写锁的进入,读锁可以是并发读取统一资源的。

通常发生在DDL语句\DML不走索引的语句中,比如这个DML update table set columnA=”A” where columnB=“B”. 

如果columnB字段不存在索引(或者不是组合索引前缀),会锁住所有记录也就是锁表。如果语句的执行能够执行一个columnB字段的索引,那么会锁住满足where的行(行锁)。

通过SELECT * from information_schema.INNODB_TRX这一句可以看每个事务的锁的情况

我在事务A中查询一条数据

select * from tab1 where column1 = xxx for update   column1是没有索引的

这时trx_rows_locked锁的是全表的数量,当我给column1加上索引时,就只锁了一行

  • mysql锁策略:row lock(行锁)

行锁可以最大限度的支持并发处理,当然也带来了最大开销,顾名思义,行锁的粒度实在每一条行数据。

 

REPEATABLE READ(可重复读)

一个事务中多次执行统一读SQL,返回结果一样。 
这个隔离级别解决了脏读的问题,幻读问题(现在网络上还有很多文章说,Repetable read级别会有幻读问题,其实已经没有了)。这里指的是innodb的rr级别,innodb中使用next-key锁对”当前读”进行加锁,锁住行以及可能产生幻读的插入位置,阻止新的数据插入产生幻行。 

多版本并发控制-MVCC

MVCC(multiple-version-concurrency-control)是个行级锁的变种,它在普通读情况下避免了加锁操作,因此开销更低。 
虽然实现不同,但通常都是实现非阻塞读,对于写操作只锁定必要的行。

  • 一致性读 (就是读取快照) 
    select * from table ….;
  • 当前读(就是读取实际的持久化的数据) 
    特殊的读操作,插入/更新/删除操作,属于当前读,处理的都是当前的数据,需要加锁。 
    select * from table where ? lock in share mode; 
    select * from table where ? for update; 
    insert; 
    update ; 
    delete;

注意:select …… from where…… (没有额外加锁后缀)使用MVCC,保证了读快照(mysql称为consistent read),所谓一致性读或者读快照就是读取当前事务开始之前的数据快照,在这个事务开始之后的更新不会被读到。详细情况下文select的详述。

对于加锁读SELECT with FOR UPDATE(排他锁) or LOCK IN SHARE MODE(共享锁)、update、delete语句,要考虑是否是唯一索引的等值查询。

MVCC 可以保证,假如说你这条数据被很多地方用到,然后我这个地方加了锁,不会影响其它没加锁的地方,比如说我加了for update,如果没有MVCC,则所有查询都会被阻塞,有了MVCC,就只有同样加for update会被阻塞

 

写锁-recordLock,gapLock,next key lock

对于使用到唯一索引 等值查询:比如,where columnA=”…” ,如果columnA上的索引被使用到, 

那么会在满足where的记录上加行锁(for update是排他锁,lock in shared 是共享锁,其他写操作加排他锁)。这里是行级锁,record lock。

我拿id作了验证,只锁住了相关行

 

对于范围查询(使用非唯一的索引): 

比如(做范围查询):where columnA between 10 and 30 ,会导致其他会话中10以后的数据都无法插入(next key lock),从而解决了幻读问题。

事务1相关行是25行

我们用select * from information_schema.INNODB_TRX查询一下锁住的行

 

发现它锁了51行,也就是说它不仅锁了相关的25行,还锁住了周围的行.

将事务1的SQL改一下

select * from t_product where sort_id BETWEEN 182 and 183 for update; 

再次运行事务1(未提交)

然后写一新的事务2

set autocommit = 0;
START TRANSACTION;

select * from t_product where sort_id=181 for update; 

可以发现,这个查询并没有被阻塞,也就是说181的数据都没有被锁,改一下SQL

select * from t_product where sort_id=184 for update; 

就发现184的数据已经被锁了

上面的实验就是证明此文对于范围查询,锁会怎么锁的说法是对的

 

这里是next key lock 会包括涉及到的所有行。 

next key lock=recordLock+gapLock,不仅锁住相关数据,而且锁住边界,从而彻底避免幻读

 

 

 

高斯泼溅(Gaussian Splatting):3D建模的颠覆性革命 阅读详情

相关推荐

Ubuntu环境下rknn-toolkit2的安装与兼容性解析

本文详细解析了在Ubuntu系统上安装瑞芯微rknn-toolkit2工具链的完整流程与关键注意事项。文章重点剖析了rknn-toolkit2与旧版rknn-toolkit的核心兼容性问题,强调两者在API、模型格式及运行时库上互不兼容,并推荐使用Conda虚拟环境进行隔离管理,为RK3566、RK3588等开发板的AI模型部署提供清晰的实践指南。

weixin_29041767的博客 374

死锁产生的原因和解决方法

1)、A程序执行了对 tableA 的 insert ,并还未 commite时,B程序也对tableA 进行insert 则此时会发生资源正忙的异常 就是锁表;2、锁表的原理是 数据库使用独占式封锁机制,当执行上面的语句时,对表进行锁住,直到发生commite 或者 回滚 或者退出数据库用户;2)、锁表常发生于并发而不是并行(并行时,一个线程操作数据库时,另一个线程是不能操作数据库的,cpu 和i/o 分配原则)减少insert 、update 、delete 语句执行 到 commite 之间的时间。

k1110的博客 1836

使用moveit中的报错及解决

1.fatal error: moveit/move_group_interface/move_group.h: 没有那个文件或目录。// #include <moveit/move_group_interface/move_group.h> 改为。问题1 moveit/move_group_interface/move_group.h: 没有那个文件或目录。在运行c++程序时报错。

qq_60566155的博客 2285

Mysql锁机制

通过上诉共享读锁、独占写锁分析可知。共享读锁只多线程允许读,但都不允许更改数据与表结构。独占写锁只允许获取锁线程操作数据与表结构,其他都只能阻塞等待获取锁。通过上面三个类型锁的介绍,大家都有了一定的认识,元数据锁中的共享读/写锁,是真正的共享。排他锁是互斥的,这个主要是为了避免DQL语句执行过程中其他事务在执行DDL语句。类型锁描述selectshare_read(共享读锁)share_read与share_write兼容的,可以互相存在。share_write(共享写锁)

2401_85207246的博客 1218

C#粘包和分包问题及解决方法

一:通过图解法来描述一下分包和粘包,这样客户更清晰直观的了解:  下面对上面的图进行解释:  1.正常情况:如果Socket Client 发送的数据包,在Socket Server端也是一个一个完整接收的,那个就不会出现粘包和分包情况,数据正常读取。  2.粘包情况:Socket Client发送的数据包,在客户端发送和服务器接收的情况下都有可能发送,因为客户端发送的数据都是发送的一个缓冲...

weixin_42033401的博客 7767

利用docx4j与docx4j-ImportXHTML高效实现HTML到Word的自动化转换

本文详细介绍了如何利用docx4j与docx4j-ImportXHTML库,在Java环境中高效实现HTML到Word文档的自动化转换。内容涵盖从环境搭建、核心依赖配置,到集成Spring Boot REST API的完整实战流程,并深入解析了处理图片、CSS样式、字体设置以及使用模板保证样式统一等高级技巧与常见问题解决方案,帮助开发者构建稳定的文档自动化生成流水线。

cnn8visionary的博客 365

导致锁表的原因及解决方法

一、导致锁表的原因 1、锁表发生在insert update 、delete 中; 2、锁表的原理是 数据库使用独占式封锁机制,当执行上面的语句时,对表进行锁住,直到发生commite 或者 回滚 或者退出数据库用户; 3、锁表的原因 : 1)、A程序执行了对 tableA 的 insert ,并还未 commite时,B程序也对tableA 进行insert 则此时会发生资源正忙的异常 就是锁表; 2)、锁表常发生于并发而不是并行(并行时,一个线程操作数据库时,另一个线程是不能操...

m0_58871547的博客 2万+

.NET MAUI跨平台串口通讯方案

MAUI跨平台串口通信架构设计采用分层模式,核心是共享业务逻辑层与平台特定实现。通过定义统一的ISerialPortService接口,实现了Windows、Android、iOS和macOS四大平台的串口通信功能。Windows平台使用System.IO.Ports类库,Android通过USB Host模式实现,iOS基于ExternalAccessory框架,macOS则采用IOKit。该设计支持串口连接管理、数据收发等核心功能,并通过事件机制实现异步通信。架构采用条件编译区分各平台实现,确保代码复用

冰茶的博客 1664

MySQL并发机制(二)——表锁

表的共享、独占锁: 共享锁: 类似于 JUC 下的 ReentrantReadWriteLock 下的 读锁。多个事务可以同时为数据加锁,同时访问到数据。 独占锁: 类似于 JUC 下的 ReentrantReadWriteLock 下的 写锁。同一时间,只能有一个事务获取为数据加锁。 只能有一个事务访问到数据 不同存储引擎的锁: 默认情况下:在对某个表执行SELECT、INSERT、DELETE、UPDATE语句时 (1): InnoDB是不会为这个表添加表级别的 S锁 或者 X锁 .

m0_47027420的博客 456

保姆级教程:2026版Windows电脑换新,微信QQ聊天记录无损搬家(附路径修改避坑指南)

本文提供2026版Windows电脑换新时微信QQ聊天记录无损迁移的保姆级教程,涵盖最新版微信/QQ的存储路径修改和避坑指南。通过详细步骤和实战技巧,确保数据迁移过程中不丢失任何珍贵对话记录和文件,特别适合需要保留完整聊天记录的用户。

weixin_42629815的博客 2478

生成式引擎优化(GEO)全景指南:技术架构、实施策略与未来趋势

生成式引擎优化(GEO)全景指南摘要 GEO(生成式引擎优化)是针对AI生成内容(如ChatGPT、文心一言等)的优化策略,通过结构化数据、权威建设与语义优化提升企业内容在AI答案中的引用优先级,实现“无点击曝光”。其核心价值在于从流量竞争转向信任构建,突破传统SEO局限。技术架构依托RAG(检索增强生成)、向量数据库及反馈学习机制,动态优化内容生成与引用逻辑。实施策略包括:部署结构化数据(如JSON-LD)、维护动态知识图谱、适配多模态内容(3D/VR)、联合权威机构发布白皮书。行业案例显示,美妆、智能家

解锁AI流量新红利!🚀 GEO优化(生成引擎优化)助您掌控AI搜索,让AI成为您的品牌最佳代言人! 1451

高性能 MySQL(二):并发控制(锁)

大家好,我是水滴~~ 无论何时,当多个进程或线程并发访问同一资源时,就会产生并发控制的问题。在数据库系统中,数据也是一种多用户共享的资源,为了保证数据的一致性,需要对数据操作进行并发控制,而数据库系统通常使用锁(Lock)来控制并发问题。 读写锁 当我们从表中读取一条记录时,即使同一时刻有多个用户并发读取,也不会有什么问题,因为读取并不会修改数据,所以不会出错。但当一个用户读取,而别一个用户试图删掉数据,这就会造成读取到不一致的数据。

水滴的博客 2098

【华为OD机试真题】459、小扇和小船的数字游戏、数字游戏 | 机试真题+思路参考+代码解析(CD卷)(C++、Java、Py)

### 🎃题目描述 >小扇和小船今天又玩起来了数字游戏,小船给小扇一个正整数 n(1  现在求 m 的最小值

KJ.JK 1717

深入理解 MySQL ——锁、事务与并发控制

@[toc]深入理解 MySQL ——锁、事务与并发控制 本文对 MySQL 数据库中有关锁、事务及并发控制的知识及其原理做了系统化的介绍和总结,希望帮助读者能更加深刻地理解 MySQL 中的锁和事务,从而在业务系统开发过程中可以更好地优化与数据库的交互。 1、MySQL 服务器逻辑架构 每个连接都会在 MySQL 服务端产生一个线程(内部通过线程池管理线程),比如一个 select 语句进入,MySQL 首先会在查询缓存中查找是否缓存了这个 select 的结果集,如果没有则继续执行解析、优化、执行的

weixin_52170224的博客 252

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

[转帖]深入理解 MySQL—锁、事务与并发控制

深入理解 MySQL—锁、事务与并发控制 http://www.itpub.net/2019/04/28/1723/ 跟oracle也类似 其实所有的数据库都有相同的机制.. 学习了机制才能够更好的工作,. 数据和云2019-04-28 10:45:07本文共11796个字,预计阅读需要30分钟。 本文对 MySQL 数据库中有关锁、事务及...

weixin_30755709的博客 159

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

深入理解 MySQL—锁、事务与并发控制

本文转载自“vivo 互联网技术”,已获授权。本文对 MySQL 数据库中有关锁、事务及并发控制的知识及其原理做了系统化的介绍和总结,希望帮助读者能更加深刻地理解 MyS...

Enmotech的博客 361

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

mysql会话和事务_深入理解Mysql——锁、事务与并发控制

本文对锁、事务、并发控制做一个总结,看了网上很多文章,描述非常不准确。如有与您观点不一致,欢迎有理有据的拍砖!mysql服务器逻辑架构 每个连接都会在mysql服务端产生一个线程(内部通过线程池管理线程),比如一个select语句进入,mysql首先会在查询缓存中查找是否缓存了这个select的结果集,如果没有则继续执行 解析、优化、执行的过程;否则会之间从缓存中获取结果集。mysql并发控制——...

weixin_39976575的博客 740
上一篇: redis的pub/sub机制
下一篇: 分布式事务的一点理解
AAA821
博客等级 码龄14年 19粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值