千家信息网

MySQL中有几种事务隔离级别

发表于:2025-11-13 作者:千家信息网编辑
千家信息网最后更新 2025年11月13日,这篇文章主要介绍MySQL中有几种事务隔离级别,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。数据库事务的隔
千家信息网最后更新 2025年11月13日MySQL中有几种事务隔离级别

这篇文章主要介绍MySQL中有几种事务隔离级别,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。数据库事务的隔离级别有4个,SQL标准定义了4种隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。

数据库事务有四种隔离级别:

  • 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据。

  • 提交读(Read Committed):只能读取到已经提交的数据,Oracle等多数数据库默认都是该级别。

  • 可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻读。

  • 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。

上面这样的教科书式定义第一次接触事务隔离概念的朋友看了可能会一脸懵逼,下面我们就通过具体的实例来解释四个隔离级别。

首先我们创建一个user表:

CREATE TABLE user ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE `uniq_name` USING BTREE (name)) ENGINE=`InnoDB` AUTO_INCREMENT=10 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

读未提交隔离级别

我们先将事务的隔离级别设置为read committed:

mysql> set session transaction isolation level read uncommitted;Query OK, 0 rows affected (0.00 sec)mysql> select @@session.tx_isolation;+------------------------+| @@session.tx_isolation |+------------------------+| READ-UNCOMMITTED  |+------------------------+1 row in set (0.00 sec)

在下面我们开了两个终端分别用来模拟事务一和事务二,p.s: 操作一和操作二的意思是按照时间顺序来执行的。

事务1

mysql> start transaction; # 操作1Query OK, 0 rows affected (0.00 sec)mysql> insert into user(name) values('ziwenxie'); # 操作3Query OK, 1 row affected (0.05 sec)

事务2

mysql> start transaction; # 操作2Query OK, 0 rows affected (0.00 sec)mysql> select * from user; # 操作4+----+----------+| id | name  |+----+----------+| 10 | ziwenxie |+----+----------+1 row in set (0.00 sec)

从上面的执行结果可以很清晰的看出来,在read uncommited级别下面我们在事务一中可能会读取到事务二中没有commit的数据,这就是脏读。

读提交隔离级别

通过设置隔离级别为committed可以解决上面的脏读问题。

mysql> set session transaction isolation level read committed;

事务一

mysql> start transaction; # 操作一Query OK, 0 rows affected (0.00 sec)mysql> select * from user; # 操作三+----+----------+| id | name  |+----+----------+| 10 | ziwenxie |+----+----------+1 row in set (0.00 sec)mysql> select * from user; # 操作五,操作四的修改并没有影响到事务一+----+----------+| id | name  |+----+----------+| 10 | ziwenxie |+----+----------+1 row in set (0.00 sec)mysql> select * from user; # 操作七+----+------+| id | name |+----+------+| 10 | lisi |+----+------+1 row in set (0.00 sec)mysql> commit; # 操作八Query OK, 0 rows affected (0.00 sec)

事务二

mysql> start transaction; # 操作二Query OK, 0 rows affected (0.00 sec)mysql> update user set name='lisi' where id=10; # 操作四Query OK, 1 row affected (0.06 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> commit; # 操作六Query OK, 0 rows affected (0.08 sec)

虽然脏读的问题解决了,但是注意在事务一的操作七中,事务二在操作六commit后会造成事务一在同一个transaction中两次读取到的数据不同,这就是不可重复读问题,使用第三个事务隔离级别repeatable read可以解决这个问题。

可重复读隔离级别

MySQL的Innodb存储引擎默认的事务隔离级别就是可重复读隔离级别,所以我们不用进行多余的设置。

事务一

mysql> start tansactoin; # 操作一mysql> select * from user; # 操作五+----+----------+| id | name  |+----+----------+| 10 | ziwenxie |+----+----------+1 row in set (0.00 sec)mysql> commit; # 操作六Query OK, 0 rows affected (0.00 sec)mysql> select * from user; # 操作七+----+------+| id | name |+----+------+| 10 | lisi |+----+------+1 row in set (0.00 sec)

事务二

mysql> start tansactoin; # 操作二mysql> update user set name='lisi' where id=10; # 操作三Query OK, 1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql> commit; # 操作四

在事务一的操作五中我们并没有读取到事务二在操作三中的update,只有在commit之后才能读到更新后的数据。

Innodb解决了幻读么

实际上RR级别是可能产生幻读,InnoDB引擎官方称中利用MVCC多版本并发控制解决了这个问题,下面我们验证一下Innodb真的解决了幻读了么?

为了方便展示,我修改了一下上面的user表:

mysql> alter table user add salary int(11);Query OK, 0 rows affected (0.51 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> delete from user;Query OK, 1 rows affected (0.07 sec)mysql> insert into user(name, salary) value('ziwenxie', 88888888);Query OK, 1 row affected (0.07 sec)mysql> select * from user;+----+----------+----------+| id | name  | salary |+----+----------+----------+| 10 | ziwenxie | 88888888 |+----+----------+----------+1 row in set (0.00 sec)

事务一

mysql> start transaction; # 操作一Query OK, 0 rows affected (0.00 sec)mysql> update user set salary='4444'; # 操作六,竟然影响了两行,不是说解决了幻读么?Query OK, 2 rows affected (0.00 sec)Rows matched: 2 Changed: 2 Warnings: 0mysql> select * from user; # 操作七, Innodb并没有完全解决幻读+----+----------+--------+| id | name  | salary |+----+----------+--------+| 10 | ziwenxie | 4444 || 11 | zhangsan | 4444 |+----+----------+--------+2 rows in set (0.00 sec)mysql> commit; # 操作八Query OK, 0 rows affected (0.04 sec)

事务二

mysql> start transaction; # 操作二Query OK, 0 rows affected (0.00 sec)mysql> insert into user(name, salary) value('zhangsan', '666666'); # 操作四Query OK, 1 row affected (0.00 sec)mysql> commit; # 操作五Query OK, 0 rows affected (0.04 sec)

从上面的例子可以看出,Innodb并没有如官方所说解决幻读,不过上面这样的场景中也不是很常见不用过多的担心。

串行化隔离级别

所有事务串行执行,最高隔离级别,不会出现幻读性能会很差,实际开发中很少使用到。

以上是"MySQL中有几种事务隔离级别"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

事务 级别 隔离 数据 问题 数据库 面的 就是 不用 内容 官方 实际 引擎 标准 篇文章 影响 不同 一致 三个 也就是 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 北京网络安全大会主持 高通接受网络安全管理办法 家里电脑做远程服务器 黑苹果用什么软件开发 启明星辰网络安全认证工程师 陕西戴尔服务器虚拟化多少钱 java数据库好学吗 数据库还能看到原始数据吗 关于数据库最新技术的文章 长宁区市场网络技术价格 香港软件开发工资多少钱 网络安全年会活动主题 指尖江湖手游怎么开服务器 湖州无线网络技术 网络安全画创意说明 登录苹果商店显示无法联系服务器 网络安全及舆论 软件开发流程是什么意思 后门管理服务器 贵阳软件开发培训哪里好 软件开发测试 职业规划 政治安全网络安全工作情况 战术目标指向网络技术 欧洲网络安全事件 执法局网络安全落实情况报告 华为网络安全专家是几级 怎么开发手机小软件开发 武汉临空港网络安全学院图片 老师应该如何做好网络安全工作 现存的网络安全问题有哪些
0