mysql中与并发相关的问题?

今天我们来聊聊 MySQL 中与并发相关的一些问题。作为一名资深 Python 开发工程师,我觉得这些问题不仅关乎数据库的稳定性和数据的一致性,更与我们的代码实现和业务逻辑密切相关。

尤其是在高并发环境下,如何保证数据的一致性,如何防止脏读、不可重复读和幻读等问题,真的是每个程序员都必须知道的内容。今天就通过一些简单的代码示例和场景说明,让大家更加直观地理解这些问题。

首先,我们知道 MySQL 服务端支持多个客户端同时连接,这就意味着 MySQL 会在多个事务并发执行时进行资源的竞争和调度。

而并发执行的事务中,如果没有妥善的控制,就可能会遇到一些数据一致性问题。常见的这些问题包括脏读(Dirty Read)、不可重复读(Non-repeatable Read)和幻读(Phantom Read)。那么,具体它们是怎么发生的呢?

脏读(Dirty Read)

脏读是指一个事务读到了另一个事务未提交的脏数据。如果事务 A 修改了数据,但事务 A 并没有提交,而事务 B 读取到了事务 A 修改后的数据,那就产生了脏读。如果事务 A 随后回滚了,那么事务 B 得到的数据就是无效的。这种现象就叫做脏读。

图片

举个例子,假设我们有两个事务 A 和 B,事务 A 从数据库中读取了小林的余额数据,然后进行了一次修改,但没有提交。与此同时,事务 B 也读取了小林的余额数据,这时事务 B 看到的余额已经是事务 A 修改后的数据了,即便事务 A 最终回滚了。

-- 事务 A
START TRANSACTION;
UPDATE account SET balance = balance - 100 WHERE name = '小林';
-- 事务 A 没有提交-- 事务 B
START TRANSACTION;
SELECT balance FROM account WHERE name = '小林';  -- 读到了事务 A 更新后的数据
-- 事务 B 没有更新数据,但可能会被脏数据影响

如果事务 A 最后执行回滚,那么事务 B 得到的数据就是过期数据,这就属于脏读。

如何避免脏读?
可以通过设置事务隔离级别来避免脏读,常用的隔离级别是 READ COMMITTED。在这个隔离级别下,事务 B 不会读取未提交的数据,从而避免了脏读的发生。

不可重复读(Non-repeatable Read)

不可重复读是指在同一个事务中,多次读取同一数据时,如果中间有其他事务修改了数据,就会导致前后两次读取的结果不一致。

图片

举个简单的例子,事务 A 从数据库中读取了小林的余额数据并进行了一些处理,接着事务 B 修改了余额并提交了。等事务 A 再次读取余额时,看到的数据就和第一次不一样了,这就是不可重复读。

-- 事务 A
START TRANSACTION;
SELECT balance FROM account WHERE name = '小林';  -- 读到 1000 元
-- 假设事务 A 在处理中-- 事务 B
START TRANSACTION;
UPDATE account SET balance = balance + 500 WHERE name = '小林';  -- 修改余额
COMMIT;-- 事务 A 再次读取
SELECT balance FROM account WHERE name = '小林';  -- 读到 1500 元

在上面的代码中,事务 A 在第一次读取时读到的是 1000 元,而在第二次读取时,却读到了 1500 元。造成这种现象的原因是事务 B 在事务 A 执行过程中对数据进行了修改,导致了数据不一致。

如何避免不可重复读?

可以通过使用更高的事务隔离级别来避免,比如 REPEATABLE READ。在这个隔离级别下,事务 A 不会因为其他事务的提交而看到不一致的数据。

幻读(Phantom Read)

幻读是指在同一个事务中,重复执行相同的查询时,查询结果的数量发生了变化。这种问题通常发生在对数据行进行插入、删除、更新等操作时。

如果在事务 A 查询某个条件下的记录时,事务 B 在事务 A 执行查询的过程中插入了符合条件的新记录,那么事务 A 进行第二次查询时就会看到额外的记录,从而产生幻读现象。

图片

举个例子,假设事务 A 查询余额大于 100 万的所有账户,得到了 5 条记录,然后事务 B 插入了一条新的余额大于 100 万的记录,提交事务后,事务 A 再次查询时发现记录数量变成了 6 条。这样就出现了幻读。

-- 事务 A
START TRANSACTION;
SELECT COUNT(*) FROM account WHERE balance > 1000000;  -- 查询到 5 条记录
-- 假设事务 A 在处理中-- 事务 B
START TRANSACTION;
INSERT INTO account (name, balance) VALUES ('小张', 2000000);  -- 插入一条新记录
COMMIT;-- 事务 A 再次查询
SELECT COUNT(*) FROM account WHERE balance > 1000000;  -- 查询到 6 条记录

在这个例子中,事务 A 在第一次查询时得到了 5 条记录,而在第二次查询时却得到了 6 条记录,产生了幻读现象。

如何避免幻读?
为了避免幻读问题,可以使用 SERIALIZABLE 隔离级别,它会强制事务之间的互斥,确保在一个事务运行期间不会有其他事务修改或插入数据,从而避免了幻读。

如何在 MySQL 中设置隔离级别?

MySQL 提供了不同的事务隔离级别,每种隔离级别可以有效地解决某些并发问题。常用的隔离级别有以下几种:

  1. READ UNCOMMITTED:最低的隔离级别,允许脏读。

  2. READ COMMITTED:防止脏读,但允许不可重复读和幻读。

  3. REPEATABLE READ:防止脏读和不可重复读,但允许幻读(MySQL 默认使用此级别)。

  4. SERIALIZABLE:最高的隔离级别,防止所有并发问题,但性能可能较差。

我们可以通过以下语句来设置事务隔离级别:

-- 设置隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

如果面试官问你:如何理解 MySQL 的事务隔离级别?

你的回答:

MySQL 提供了四种常见的事务隔离级别,每个级别的作用和影响如下:

  1. READ UNCOMMITTED:事务可以读取其他事务未提交的数据,可能出现脏读、不可重复读和幻读问题。

  2. READ COMMITTED:事务只能读取已提交的数据,避免了脏读问题,但仍可能发生不可重复读和幻读。

  3. REPEATABLE READ:事务在整个生命周期内读取的数据是固定的,避免了脏读和不可重复读问题,但在 MySQL 中,仍然可能出现幻读。

  4. SERIALIZABLE:事务完全串行化,避免了脏读、不可重复读和幻读问题,但会大幅影响性能。

在实际开发中,根据业务的需求选择合适的事务隔离级别非常重要。例如,如果对数据一致性要求非常高,可以选择 SERIALIZABLE,但如果对性能要求较高,可能会选择 REPEATABLE READREAD COMMITTED

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

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

相关文章

使用k6进行kafka负载测试

1.安装环境 kafka环境 参考Docker搭建kafka环境-CSDN博客 xk6-kafka环境 ./xk6 build --with github.com/mostafa/xk6-kafkalatest 查看安装情况 2.编写脚本 test_kafka.js // Either import the module object import * as kafka from "k6/x/kafka";// Or in…

[机器学习]XGBoost(3)——确定树的结构

XGBoost的目标函数详见[机器学习]XGBoost(2)——目标函数(公式详解) 确定树的结构 之前在关于目标函数的计算中,均假设树的结构是确定的,但实际上,当划分条件不同时,叶子节点包含的…

springboot444新冠物资管理系统的设计与实现(论文+源码)_kaic

摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装新冠物资管理系统软件来发挥其高效地信息处理的作用&#x…

Javascript-web API-day02

文章目录 01-事件监听02-点击关闭广告03-随机点名案例04-鼠标经过或离开事件05-可点击的轮播图06-小米搜索框07-键盘类型事件08-键盘事件-发布评论案例09-focus选择器10-评论回车发布11-事件对象12-trim方法13-环境对象14-回调函数15-tab栏切换 01-事件监听 <!DOCTYPE html…

使用xjar 对Spring-Boot JAR 包加密运行

1 Xjar 介绍 Spring Boot JAR 安全加密运行工具&#xff0c;同时支持的原生JAR。 基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动&#xff0c;动态解密运行的方案&#xff0c;避免源码泄露或反编译。 功能特性 无需侵入代码&#xff0c;只需要把编译好的…

深度学习的下一站:解锁人工智能的新边界

引言&#xff1a;新边界的呼唤 深度学习的诞生&#xff0c;犹如人工智能领域的一次革命&#xff0c;激发了语音助手、自动驾驶、智能医疗等前沿技术的飞速发展。然而&#xff0c;面对现实世界的复杂性&#xff0c;现有的深度学习模型仍然存在数据依赖、可解释性差、环境适应力不…

基于DockerCompose搭建Redis主从哨兵模式

linux目录结构 内网配置 哨兵配置文件如下&#xff0c;创建3个哨兵配置文件 # sentinel26379.conf sentinel26380.conf sentinel26381.conf 内容如下 protected-mode no sentinel monitor mymaster redis-master 6379 2 sentinel down-after-milliseconds mymaster 60000 s…

upload-labs靶场1-19关

第 1 关&#xff08;删除前端js校验&#xff09; 点击第一关&#xff0c;我们可以看到页面上传区可以上传一个图片&#xff0c;我们要上传一个 webshell&#xff0c;这里我们上传一句话木马的 php 点击上传 显示文件不支持上传&#xff0c;这时我们查看源码 查看代码后发现&am…

vue3+vite 引入动画组件库 Inspira UI

关于Inspira UI Inspira UI不是传统的组件库。相反&#xff0c;它是精选的优雅组件集合&#xff0c;您可以轻松将其集成到您的应用程序中。只需选择所需的组件&#xff0c;复制代码&#xff0c;然后自定义以适合您的项目即可。您可以随意使用和修改代码&#xff01; 官网地址…

Go语言启动独立进程

文章目录 问题解决方案1. **将 npc.exe 启动为独立的进程**2. **修改 exec.Command 函数**示例代码解释为什么这样有效注意 问题 在你当前的代码中&#xff0c;调用 exec.Command("XXX.exe") 启动 XXX.exe 程序时&#xff0c;这个程序是由 Go 程序直接启动的。如果 …

计算机网络错题

文章目录 码分复用透明传输差错检测停止-等待协议回退N帧协议CSMA/CD协议以太网交换机Vlanip地址的无分类编制方法ip地址的应用规划ip数据包的发送和转发过程路由信息协议IPI2016201720202022 2.5信道 码分复用 透明传输 差错检测 停止-等待协议 回退N帧协议 CSMA/CD协议 以太网…

使用Docker启用MySQL8.0.11

目录 一、Docker减小镜像大小的方式 1、基础镜像选择 2、减少镜像层数 3、清理无用文件和缓存 4、优化文件复制&#xff08;COPY和ADD指令&#xff09; 二、Docker镜像多阶段构建 1、什么是dockers镜像多阶段构建 1.1 概念介绍 1.2 构建过程和优势 2、怎样在Dockerfil…

Zabbix6.0升级为7.2

Zabbix 7.0 进行了全新升级&#xff0c;本文讲解如何从 6.0 版本升级至最新版本 7.2。在 CentOS 8 上通过RPM 方式安装 Zabbix 服务 一、环境信息 我是CentOS 7安装的服务端&#xff0c;在该机器在通过源码去安装 Zabbix 7.0 版本的话&#xff0c;会比较费劲&#xff0c;因为有…

2024.4 评估大语言模型在医疗行业应用的综合调查

A Comprehensive Survey on Evaluating Large Language Model Applications in the Medical Industry https://arxiv.org/abs/2404.15777 问题 大语言模型&#xff08;LLMs&#xff09;在医疗领域应用广泛&#xff0c;但缺乏专门针对其在医疗应用中有效性、准确性、可用性和…

apache应用(客户机地址限制、用户授权限制、日志分割、AWStats日志分析)

目录 一、 客户机地址限制 二、 用户授权限制 三、 日志分割 使用rotatelogs分割工具 使用第三方工具cronolog 四、 AWStats日志分析 具体的apache软件安装可以阅读我之前的文章apache安装https://blog.csdn.net/m0_68472908/article/details/139348739?spm1001.2014.300…

web3跨链预言机协议-BandProtocol

项目简介 Band Protocol 项目最初于 2017年成立并建立在 ETH 之上。后于2020年转移到了 Cosmos 网络上&#xff0c;基于 Cosmos SDK 搭建了一条 Band Chain 。这是一条 oracle-specific chain&#xff0c;主要功能是提供跨链预言机服务。Cosmos生态上第一个&#xff0c;也是目…

STM32二刷学习笔记--GPIO

文章目录 GPIO使用详解GPIO基本结构GPIO工作模式简单示例推挽输出LED闪烁按键控制LED闪烁**LED控制函数****按键控制函数** GPIO使用详解 在STM32开发中&#xff0c;GPIO&#xff08;通用输入输出&#xff09;是与外设接口的基础模块。通过GPIO&#xff0c;我们可以连接各种外…

ECharts柱状图-柱图38,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个柱状图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供…

WPF ControlTemplate 控件模板

区别于 DataTemplate 数据模板&#xff0c;ControlTemplate 是控件模板&#xff0c;是为自定义控件的 Template 属性服务的&#xff0c;Template 属性类型就是 ControlTemplate。 演示&#xff0c; 自定义一个控件 MyControl&#xff0c;包含一个字符串类型的依赖属性。 pub…

Pytest-Bdd vs Behave:选择最适合的 Python BDD 框架

Pytest-Bdd vs Behave&#xff1a;选择最适合的 Python BDD 框架 Pytest BDD vs Behave&#xff1a;选择最适合的 Python BDD 框架BDD 介绍Python BDD 框架列表Python BehavePytest BDDPytest BDD vs Behave&#xff1a;关键区别Pytest BDD vs Behave&#xff1a;最佳应用场景结…