MySQL并发事务问题及隔离级别操作演示(附详细图文)

 更新时间:2025年08月28日 08:33:11   作者:学Java的小半  
在高并发环境下,数据库事务操作可能引发脏读、不可重复读、幻读和丢失更新等数据一致性问题,这篇文章主要介绍了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_increment
        primary 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 (串行化)

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

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

左窗:

总结

到此这篇关于MySQL并发事务问题及隔离级别操作演示的文章就介绍到这了,更多相关MySQL并发事务及隔离级别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入mysql "ON DUPLICATE KEY UPDATE" 语法的分析

    深入mysql "ON DUPLICATE KEY UPDATE" 语法的分析

    本篇文章是对mysql "ON DUPLICATE KEY UPDATE"语法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • MySQL在读已提交和可重复读这两个不同事务隔离级别下幻读的区别及说明

    MySQL在读已提交和可重复读这两个不同事务隔离级别下幻读的区别及说明

    这篇文章主要介绍了MySQL在读已提交和可重复读这两个不同事务隔离级别下幻读的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • Docker搭建MySQL数据库的完整步骤及报错解决

    Docker搭建MySQL数据库的完整步骤及报错解决

    使用Docker部署MySQL数据库是一种高效且便捷的方法,这篇文章主要介绍了Docker搭建MySQL数据库的完整步骤及报错解决,文中通过代码介绍介绍的非常详细,需要的朋友可以参考下
    2025-07-07
  • mysql 删除操作(delete+TRUNCATE)

    mysql 删除操作(delete+TRUNCATE)

    这篇文章主要介绍了mysql 删除操作,主要包括了delete与TRUNCATE的使用,需要的朋友可以参考下
    2014-11-11
  • mysql免安装版配置教程

    mysql免安装版配置教程

    这篇文章主要为大家详细介绍了mysql免安装版配置教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • 非常实用的MySQL函数全面总结详解示例分析教程

    非常实用的MySQL函数全面总结详解示例分析教程

    这篇文章主要为大家介绍了非常实用的MySQL函数的详解示例分析,文中全面的概括了MySQL函数,并进行了详细的示例讲解,有需要的朋友可以借鉴参考下
    2021-10-10
  • 解读mysql中的null问题

    解读mysql中的null问题

    这篇文章主要介绍了解读mysql中的null问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • mysql 教程 存储过程

    mysql 教程 存储过程

    最近用mysql + asp.net来写网站,既然mysql已经支持存储过程了,那么像分页这么常用的东西,当然要用存储过程啦
    2009-06-06
  • Mysql 5.7.9 shutdown 语法实例详解

    Mysql 5.7.9 shutdown 语法实例详解

    之前如果想关闭一个mysql数据库可以通过kill 命令、mysqladmin shutdown 、service mysqld stop 等这样的方式。然而在mysql-5.7.9之后mysql终于提供了SQL接口的shutdown语法啦
    2017-06-06
  • MySQL ENUM一个字段引发的故障踩坑实录

    MySQL ENUM一个字段引发的故障踩坑实录

    Mysql中的enum类型就是我们常说的枚举类型,它的取值范围需要在创建表时通过枚举方式(一个个的列出来)显式指定,这篇文章主要介绍了MySQL ENUM一个字段引发的故障踩坑实录的相关资料,需要的朋友可以参考下
    2026-01-01

最新评论