生产环境的 MySQL事务隔离级别

MySQL 数据库的默认隔离级别是 RR( 可重复读 ),但是很多大公司把隔离级别改成了 RC(读已提交),主要原因是为了提高并发和降低死锁概率

为了解决幻读的问题 RR 相比 RC 多了间隙锁( gap lock )和临键锁( next-keylock )。而 RC 中修改数据仅用行锁,锁定的范围更小,因此相比而言 RC的并发更高。

创建如下的表,并插入一些记录

CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB;
INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2);

此时执行SQL-A ,且未提交事务

UPDATE t SET b = 5 WHERE b = 3;

在 RR 即可重复隔离级别情况下,会锁哪几条数据呢?

答案是会锁定所有符合条件的行,并且为了防止幻读,还会锁定这些行之间的间隙。

x-lock(2,3) 和 x-lock(4,3)  -- 这两行会被更新并保留X锁。
x-lock(1,2)、x-lock(3,2) 和 x-lock(5,2) -- 这些行虽然不符合更新条件,但由于间隙锁的存在,它们也会被锁定以防止其他事务插入新的行

可以看到全锁了,此时执行 SQL-B:

UPDATE t SET b = 4 WHERE b = 2;

就会被阻塞了。因此,在RR隔离级别下,UPDATE t SET b = 5 WHERE b = 3; 会锁定所有行,包括那些不符合更新条件的行。

而执行 SQL-A 在 RC 即读已提交隔离级别下,会锁哪几条数据呢?

x-lock(1,2); unlock(1,2)
x-lock(2,3); update(2,3) to (2,5); 保留 x-lock
x-lock(3,2); unlock(3,2)
x-lock(4,3); update(4,3) to (4,5); 保留 x-lock
x-lock(5,2); unlock(5,2)
-- 只会锁定符合更新条件的行,即 b = 3 的行,因为RC级别不使用间隙锁。

可以看到,只锁了两条数据,此时执行 SQL-B 会怎样?

x-lock(1,2); update(1,2) to (1,4); 保留 x-lock
x-lock(2,3); unlock(2,3)
x-lock(3,2); update(3,2) to (3,4); 保留 x-lock
x-lock(4,3); unlock(4,3)
x-lock(5,2); update(5,2) to (5,4); 保留 x-lock

可以看到仅锁了 b=2 的数据,完美避开了 SQL-A加的锁

此时可能有同学会有疑问: SQL-B 不是应该被 (2, 3 )这行的锁给阻塞吗?

半一致性读(“semi-consistent”read)

这其实也是 InnoDB 做的一个优化。

  • 在执行 update 的时候,扫描发现当前行已经被锁定了,它就会执行半一致性读的操作,得到当前数据的最新版本(上述中 SQL-A 锁定的行最新版本的已提交数据,b都为5 ),来判断是否和当前的(SQL-B)update 的 where 条件匹配

  • 如果匹配则说明当前的 update也需要锁定这行

  • 因此需要等待。如果不匹配说明它们之间没关联,因此不需要等待锁,这个优化提升了并发度。

所以 RC + 半一致性读 能进一步的提升 SQL 执行的并发度。

并且 RC 锁的粒度更小,意味着死锁的概率会更低,但是缺点是可能会产生幻读,这个就需要业务自已评估幻读的问题(大部分情况下都没啥影响)。

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

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

相关文章

Oracle(windows安装遇到的ORA-12545、ORA-12154、ORA-12541、ORA-12514等问题)

其实出现该问题就是监听或者服务没有配好。 G:\xiaowangzhenshuai\software\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMINlistener.ora SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME CLRExtProc)(ORACLE_HOME G:\xiaowangzhenshuai\software\Oracle\product\11.2.0\d…

Mac上搭建k8s环境——Minikube

1、在mac上安装Minikube可执行程序 brew cask install minikub 安装后使用minikube version命令查看版本 2、安装docker环境 brew install --cask --appdir/Applications docker #安装docker open -a Docker #启动docker 3、安装kubectl curl -LO https://storage.g…

OpenAI 实战进阶教程 - 第二节:生成与解析结构化数据:从文本到表格

目标 学习如何使用 OpenAI API 生成结构化数据(如 JSON、CSV 格式)。掌握解析数据并导出表格文件的技巧,以便适用于不同实际场景。 场景背景 假设你是一名开发人员,需要快速生成一批产品信息列表(如名称、价格、描述…

PostgreSQL 中进行数据导入和导出

在数据库管理中,数据的导入和导出是非常常见的操作。特别是在 PostgreSQL 中,提供了多种工具和方法来实现数据的有效管理。无论是备份数据,还是将数据迁移到其他数据库,或是进行数据分析,掌握数据导入和导出的技巧都是…

【Gitlab】虚拟机硬盘文件丢失,通过xx-flat.vmdk恢复方法

前言 由于近期过年回家,为了用电安全直接手动关闭了所有的电源,导致年后回来商上电开机后exsi上的虚拟机出现了问题。显示我的gitlab虚拟机异常。 恢复 开机之后虚拟机异常,通过磁盘浏览发现gitlab服务器下面的虚拟机磁盘文件只有一个xxx-f…

如何在自己mac电脑上私有化部署deep seek

在 Mac 电脑上私有化部署 DeepSeek 的步骤如下: 1. 环境准备 安装 Homebrew(如果尚未安装): Homebrew 是 macOS 上的包管理工具,用于安装依赖。 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com…

DeepSeek服务器繁忙问题的原因分析与解决方案

一、引言 随着人工智能技术的飞速发展,DeepSeek 等语言模型在众多领域得到了广泛应用。然而,在春节这段时间的使用过程中,用户常常遭遇服务器繁忙的问题,这不仅影响了用户的使用体验,也在一定程度上限制了模型的推广和…

python的ruff简单使用

Ruff 是一个用 Rust 编写的高性能 Python 静态分析工具和代码格式化工具。它旨在提供快速的代码检查和格式化功能,同时支持丰富的配置选项和与现有工具的兼容性。ruff是用rust实现的python Linter&Formatter。 安装: conda install -c conda-forge…

第16章 Single Thread Execution设计模式(Java高并发编程详解:多线程与系统设计)

简单来说, Single Thread Execution就是采用排他式的操作保证在同一时刻只能有一个线程访问共享资源。 1.机场过安检 1.1非线程安全 先模拟一个非线程安全的安检口类,旅客(线程)分别手持登机牌和身份证接受工作人员的检查,示例代码如所示。…

C# 压缩图片并保存到本地

本文主要介绍如何使用C#将图片进行压缩并保存到本地。 接收一个原始图片的字节数组、需要保存的图片类型、输出路径和图片质量。方法首先将字节数组转换为一个内存流,然后使用Image.FromStream方法将内存流转换为一个Image对象。接下来,方法创建一个编码…

项目练习:重写若依后端报错cannot be cast to com.xxx.model.LoginUser

文章目录 一、情景说明二、解决办法 一、情景说明 在重写若依后端服务的过程中 使用了Redis存放LoginUser对象数据 那么,有存就有取 在取值的时候,报错 二、解决办法 方法1、在TokenService中修改如下 getLoginUser 方法中:LoginUser u…

操作系统和中间件的信息收集

在浏览器中收集操作系统与中间件信息时,主要通过客户端JavaScript(用于操作系统/浏览器信息)和服务器端脚本(用于中间件信息)实现。以下是分步指南: 一、客户端操作系统信息收集(JavaScript&am…

高级sql技巧 从复杂查询到性能优化 提升数据处理效率

在数据驱动的时代,SQL(结构化查询语言)是数据库管理和数据分析中不可或缺的工具。随着数据复杂度和数据量的增加,掌握 SQL 的高级技巧不仅能帮助我们高效处理复杂的数据查询,还能极大地提高数据库的性能和数据处理效率…

QT 窗口A覆盖窗口B时,窗口B接受不到鼠标事件

一、问题 在项目的需求中,地图A上面需要叠放一个任务窗口B,B覆盖了A,导致A接受不到鼠标及滚轮事件。 二、解决方案 1、Qt::WA_TransparentForMouseEvents 是 Qt 框架中的一个属性,用于使指定的控件及其子控件不响应鼠标事件。当启…

爱普生L3153打印机无线连接配置流程

家里使用的是移动宽带中兴路由器,有WPS功能,进入192.168.1.1管理员页面,用户名user,密码在路由器背面(可以登录后修改密码)。在网络-WLAN网络配置-WPS中,点击push button,激活路由器…

计算机网络知识速记:HTTP与HTTPS

计算机网络知识速记:HTTP与HTTPS 一、HTTP基础知识 HTTP(超文本传输协议)是一个无状态的协议,通常用于在客户端与服务器之间传输数据。HTTP采用的是一种请求-响应模型,客户端发出请求后,服务器返回数据。…

简述mysql 主从复制原理及其工作过程,配置一主两从并验证。

MySQL 主从复制工作过程 1、二进制日志记录(Binary Logging): 主服务器开启二进制日志记录功能,将所有更改数据的操作(如 INSERT、UPDATE、DELETE)记录到二进制日志文件中。 2、日志传输(Log…

Rust枚举(Enum)完全指南:用类型安全表达多样性

枚举(Enum)是Rust类型系统的核心特性之一,它不仅能够表示简单的选项集合,还能携带复杂数据,配合模式匹配实现强大的逻辑控制。本文将通过具体示例,深入解析Rust枚举的完整用法。 一、基础枚举定义 1.1 简单…

Python Pandas(3):DataFrame

1 介绍 DataFrame 是 Pandas 中的另一个核心数据结构,类似于一个二维的表格或数据库中的数据表。它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由…

ubuntu下迁移docker文件夹

在 Ubuntu 系统中迁移 Docker 文件夹(如 Docker 数据存储文件夹 /var/lib/docker)到另一个磁盘或目录,通常是为了释放系统盘空间。以下是迁移过程的详细步骤: 1. 停止 Docker 服务 在进行迁移之前,必须停止 Docker 服…