当前位置: 首页 > news >正文

MySQL并发事务问题及隔离级别演示

举例演示了MySQL的并发事务问题,以及四个事务隔离级别的区别,例子直接跳转标题3.

1.并发事务问题

(1)脏读 (Dirty Read)

  • 问题描述:一个事务读取了另一个未提交事务修改过的数据

  • 示例

    • 事务A修改了某行数据但未提交

    • 事务B读取了事务A修改后的数据

    • 事务A回滚,事务B读取的数据就是无效的"脏数据"

(2)不可重复读 (Non-repeatable Read)

  • 问题描述:在同一事务内,多次读取同一数据返回不同结果(因为其他事务修改并提交了该数据)

  • 示例

    • 事务A第一次读取某行数据

    • 事务B修改了该行数据并提交

    • 事务A再次读取同一行数据,发现数据已改变

(3) 幻读 (Phantom Read)

  • 问题描述:在同一事务内,多次查询返回不同的行集合(因为其他事务新增或删除了数据)

  • 示例

    • 事务A查询表中符合某条件的行

    • 事务B插入新的符合该条件的行并提交

    • 事务A再次查询,发现多出了"幻影行"

2.事务隔离级别

我们可以通过给事务设置隔离级别来解决上述并发问题

MySQL 提供了四种隔离级别

隔离级别脏读不可重复读幻读说明
READ UNCOMMITTED (读未提交)可能可能可能最低隔离级别,性能最好但问题最多
READ COMMITTED (读已提交)可能可能不可能只读取已提交的数据,Oracle默认级别
REPEATABLE READ (可重复读)可能不可能不可能MySQL默认级别,确保同一事务内读取一致
SERIALIZABLE (串行化)不可能不可能不可能最高隔离级别,性能最差但最安全

事务隔离级别的相关操作

查看当前隔离级别

SELECT @@transaction_isolation;
-- 或
SHOW VARIABLES LIKE 'transaction_isolation';

设置隔离级别

可以设置全局级别或会话级别:

-- 设置全局隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;-- 设置当前会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;-- 设置下一个事务的隔离级别
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

3.操作演示

(1).准备数据

首先,准备一个简单的数据表做演示

这里是一个简单的账户表

create table account
(user_name varchar(20) not null,money     double      null,id        int auto_incrementprimary key
);# 添加数据
insert into account values ('jack',8000,1),('mary',8000,2);

因为要演示并发问题,所以,我们直接使用cmd打开两个窗口演示

找到 上面表所在的数据库

(2).脏读

我们先演示,脏读:一个事务读取了另一个未提交事务修改过的数据

先设置左窗口的事务隔离级别为  read uncommitted

set session transaction isolation level read uncommitted ;

然后在左窗开启一个事务,查询一下 account表的数据:

接着在右窗开启一个事务,修改 一下 account表的数据:

注意,这时我们并没有commit 提交右窗修改的数据

但是,我们再在左窗查询 数据,却发现查询到的数据已经修改了

这就体现了脏读问题,右窗的事务,访问到了左窗事务还未提交的数据!

演示完成,别忘了结束两边的事务,再进行后续操作

我们把右窗事务隔离级别修改为 readcommited 就可以避免脏读问题

就是下面 不可重复读的操作演示,不再赘述

右窗:

左窗:

(3.1).不可重复读

右窗事务隔离级别设置为 readcommited

开启一个事务,查询一下数据

在左窗开启一个事务,修改表中数据

左窗还未提交zai再次在右窗查询,发现数据没有变化,也就是解决了 脏读问题

左窗提交数据后再次在右窗查询,发现数据变化了,

在右窗的一个事务过程中,出现了多次读取同一数据但返回不同结果的现象,这就是不可重复读

(3.2)解决不可重复读

 设置右窗事务隔离级别为REPEATABLE READ (可重复读), 开启一个事务,查询当前表数据

左窗还是开启一个事务,修改表中数据,这次我们直接提交!

右窗再次查询表数据,可以看到,这次左窗事务虽然已经提交了修改,但是右窗查询数据还是没变。这样一个事务里就不会出现多次读取同一数据但返回不同结果的现象,这就解决了上面 不可重复的的问题

我们结束右窗事务后,再次查询,则看到了最新数据

(4.1).幻读

右窗不改变隔离级别,依旧为  repeatable read 

开启新事务,查询id为3的信息,当前没有id为3的人,当然查询不到

此时,左窗开启一个事务,插入id= 3的一条数据 ,并直接提交

由于,并发执行,之前右窗没有查询到id= 3的数据,于是也准备插入一条id= 3的数据,但是由于左窗已经插入完成,所以无法插入。如下图

右窗再次查询id为3的信息,但是还是查询不到

像这样右窗这样,查询时查询不到,插入时又认为数据已经存在不让插入 的现象 就叫 幻读

(4.2).解决幻读

设置右窗事务隔离级别为SERIALIZABLE (串行化),开启事务,查询id= 4的数据,没有

左窗开启事务,插入id= 4的一条数据,但是按回车后,却没有运行,这就是因为 右窗事务隔离级别为SERIALIZABLE (串行化)

  • 所有事务只能串行执行,解决了所有并发问题

只能在右窗执行完当前事务的全部操作后,左窗事务才能继续!

左窗:

=================结束==================

文章创作不易

求点赞!

求评论!

求收藏!

http://www.xdnf.cn/news/644365.html

相关文章:

  • 蓝桥杯单片机答题技巧
  • DNS 入门篇
  • Arduino Uno KY-037声音传感器实验
  • 短视频矩阵系统源码部署分享
  • 维护测试监控LLM应用
  • 从厨房到储物间:Grocy 家庭的智能物资管理助手
  • CA自签名证书创建--证书链生成脚本
  • dify-plugin-daemon的.env配置文件
  • 大模型和AI工具汇总(一)
  • CMake学习笔记(六)可以在CMake的function中修改function函数体之外的变量值吗?
  • 【FastAPI】--进阶教程1
  • VS2022 安装CodeGeeX AI插件实现高效编程体验
  • 贪心算法应用:贝尔曼-福特松弛问题详解
  • 差分数组知识笔记
  • 嵌入式学习笔记——day26
  • C++ gtest单元测试
  • STM32八股【10】-----stm32启动流程
  • 如何利用好cursor
  • 【第四十六周】文献阅读:从 RAG 到记忆:大型语言模型的非参数持续学习
  • c++ overwrite
  • 华为OD机试真题——仿LISP运算(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
  • Linux应用程序 栈溢出 内存踩踏 问题 排查学习
  • 第九课 影像文章插图及图表制作完全指南:从原理到应用
  • 市场需求文档撰写
  • C++11(2):
  • 《算法导论(第4版)》阅读笔记:p1178-p1212
  • 吴恩达机器学习笔记:逻辑回归3
  • Python元类(Metaclass)深度解析
  • Volatile的相关内容
  • Lombok与Jackson实现高效JSON序列化与反序列化