[MySQL]事务的隔离级别原理与底层实现

news/2025/2/5 19:58:19/

目录

1.为什么要有隔离性

2.事务的隔离级别

读未提交

读提交

可重复读

串行化

3.演示事务隔离级别的操作

查看与设置事务的隔离级别

演示读提交操作

演示可重复读操作


1.为什么要有隔离性

        在真正的业务场景下,MySQL服务在同一时间一定会有大量的客户端进程并发的去访问同一个MySQL服务,而且一定会同一时间有多个客户端访问和操作同一张表。而且我们在业务层面,一个事务很多情况下都需要多条SQL语句组成,那么这样的话,操作虽然是原子性的,但是过程却可以明显的分成执行前、执行中以及执行后三个阶段。

        那么在执行中的阶段,一个客户端在执行事务操作数据库表,但是事务还没有完成提交,其其他客户端如果查看到该客户端没有提交的数据,会不会有问题呢?如果客户端查看了另一个客户端没有提交的数据,但是另一个客户端最后执行了回滚操作,那么该客户端查看的数据就不是真实的数据了,出现了数据的二义性。

        所以说为了保证数据库在执行事务操作过程中尽量不受到干扰,就有了一个重要的特性就是隔离性。但是也并非客户端在执行事务的时候,不能让其他客户端查看自己没有提交的数据,在一些更关注数据的实时性的业务操作中,就能够接受短暂的数据不一致问题。

2.事务的隔离级别

        事务的隔离级别分为读未提交、读提交、可重复读、串行化,不同的隔离界别可以让蛇舞收到不同程度的干扰,可以用于不同的业务场景。对于隔离级别的实现基本上都是通过锁实现了,因为多客户端访问也相当于是多线程的并发访问,所以说还是要用锁。对于不同的隔离级别,锁的使用是不同的,常见的有表锁、行锁、读锁、写锁等等。

        对于事务的隔离级别是相对于自己而言的,如果说一个客户端A是读未提交,客户端B是读提交,那么客户端B想要提取客户端A在事务中操作的结果就需要在客户端A提交之后才可以看得到。

读未提交

        该隔离级别属于是最低的隔离界别,相当于没隔离一样,所有的事物都可以看到其他事物没有提交的执行结果,这种隔离界别在实际的业务中基本上是不会使用的。会有很多的并发问题,例如脏读、幻读、不可重复读等问题。

事务的并发问题

脏读

一个事务读取到了另一个事务未提交的操作结果就是脏读。由于未提交的事务数据可能回因为事务的回滚而改变,所以读到的数据可能回出问题。

幻读

在一个事务内,按照某个条件进行数据查询的时候,第一次查询和第二次查询的结果集不同。可能是因为其他事务在这个期间对数据进行了操作。

不可重复读

在一个事务内,对于同一个数据的多次读取结果不一致叫做不可重复读。可能因为在该事务执行期间,其他事务对这个数据进行了修改等操作,导致了读取数据的变化,造成了该问题。

        脏读更加聚焦于数据的插入和删除操作,两次查看的数据量不一样,而不可重复读更聚焦于数据的修改和删除的操作,两次查看的数据量可能一样,但是里面的数据不一样。

读提交

        该隔离级别是大多数数据库的默认隔离级别(但不是MySQL的),也是普遍理解上最合适的一个隔离级别。该隔离级别规定了,一个事务只能看到其他的已经提交的事务所改变的数据操作。这种级别的隔离就不会产数据的脏读问题了。因为只能读取到提交之后的存放在磁盘当中的永久化数据。但是还是会有不同重复读取的问题,因为多次查看表数据的时候,在此其他其他事务可能回修改表并提交事务。

可重复读

        这是MySQL的默认隔离级别,他确保同一个事务,在执行的过程中多次读取操作数据的时候,回看到同样的数据行。使得数据不会出现脏读、不可重复读取的问题,但是会有幻读的问题。

串行化

        串行化是数据库事务隔离级别中最高的级别。在串行化隔离级别下,事务的执行是顺序的,一个事务必须等待前一个事务完成(提交或者回滚)之后才能开始执行,在等待过程中就会放入等待队列。就好像多个事务是在一条单行道上排队依次通过一样,完全避免了并发事务之间的相互干扰。他会在每个读的数据行上面加上共享锁,但是加锁就会有锁的竞争问题,会大大降低效率。这种级别不会有任何的事务之间相互影响的问题了。

3.演示事务隔离级别的操作

查看与设置事务的隔离级别

        事务隔离级别的设置分为全局的和会话级别的设置,如果设置会话级别的话,就相当于是对于一个客户端连接的设置,关闭之后再重启还是会重制事务的隔离级别,会按照全局的事务隔离界别来定义。

        对于设置会话级别的事务隔离性不需要重启服务器,但是设置全局级别话需要重启,因为事务的隔离级别是受会话影响的,客户端启动的会话隔离级别是从全局隔离级别复制过来的,所以说全局隔离级别决定了客户端启动的时候的事务隔离级别,但是事务在操作的时候,是看会话的事务隔离级别的。

查看语法:SELECT @@[SESSION | GLOBAL].TRANSACTION_ISOLATION;

设置语法:SELECT [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE };

演示读提交操作
//客户但A————————————————————————————————————————————————————————
//设置会话隔离级别为读提交
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)//开启事务
mysql> begin;
Query OK, 0 rows affected (0.00 sec)//插入与提交事务
mysql> insert into account values(1, '张三', 100), (2, '李四', 200);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0mysql> commit;
Query OK, 0 rows affected (0.01 sec)//客户但B————————————————————————————————————————————————————————
//设置会话隔离级别为读提交
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)//开启事务
mysql> begin;
Query OK, 0 rows affected (0.00 sec)//在客户端A提交之前查看表数据
mysql> select * from account;
Empty set (0.00 sec)//在客户端A提交之后查看表数据
mysql> select * from account;
+----+--------+--------+
| id | name   | blance |
+----+--------+--------+
|  1 | 张三   | 100.00 |
|  2 | 李四   | 200.00 |
+----+--------+--------+
2 rows in set (0.00 sec)//提交数据
mysql> commit;
Query OK, 0 rows affected (0.00 sec)

        该操作,客户端B在事务期间,两次查看表数据的数据不一样,这就是不可重复读。

演示可重复读操作
//客户但A————————————————————————————————————————————————————————
//设置会话隔离级别为可重复读
mysql> set session transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec)//开启事务,插入数据,提交事务
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into account values(3, '王五', 300);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)//客户但B————————————————————————————————————————————————————————
//设置会话隔离级别为可重复读
mysql> set session transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec)//开启事务
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
//客户端A提交之前
mysql> select * from account;
+----+--------+--------+
| id | name   | blance |
+----+--------+--------+
|  1 | 张三   | 100.00 |
|  2 | 李四   | 200.00 |
+----+--------+--------+
2 rows in set (0.00 sec)//客户端A提交之后
mysql> select * from account;
+----+--------+--------+
| id | name   | blance |
+----+--------+--------+
|  1 | 张三   | 100.00 |
|  2 | 李四   | 200.00 |
+----+--------+--------+
2 rows in set (0.00 sec)//提交事务
mysql> commit;
Query OK, 0 rows affected (0.00 sec)//自己提交事务之后查看表数据
mysql> select * from account;
+----+--------+--------+
| id | name   | blance |
+----+--------+--------+
|  1 | 张三   | 100.00 |
|  2 | 李四   | 200.00 |
|  3 | 王五   | 300.00 |
+----+--------+--------+
3 rows in set (0.00 sec)


http://www.ppmy.cn/news/1569591.html

相关文章

2025年时序数据库发展方向和前景分析

2025年时序数据库发展方向和前景分析 随着物联网设备激增、实时监控需求上升和数据量爆炸式增长,时序数据库(Time Series Database, TSDB)正成为关键的数据基础设施。据IDC预测,到2025年全球将有416亿联网IoT设备,每年…

前端 Vue 性能提升策略

一、引言 前端性能优化是确保 Web 应用快速响应和流畅用户体验的关键。对于使用 Vue.js 构建的应用,性能优化不仅涉及通用的前端技术,还包括针对 Vue 特性的特定优化措施。本文将从多个方面探讨如何全面提升前端和 Vue 应用的性能。 二、前端性能优化基础 1. 减少初始加载…

国产之光DeepSeek架构理解与应用分析

目录 初步探索DeepSeek的设计 一、核心架构设计 二、核心原理与优化 三、关键创新点 四、典型应用场景 五、与同类模型的对比优势 六、未来演进方向 从投入行业生产的角度看 一、DeepSeek的核心功能扩展 二、机械电子工程产业中的具体案例 1. 预测性维护(Predictive…

Python 与 PostgreSQL 集成:深入 psycopg2 的应用与实践

title: Python 与 PostgreSQL 集成:深入 psycopg2 的应用与实践 date: 2025/2/4 updated: 2025/2/4 author: cmdragon excerpt: PostgreSQL 作为开源关系型数据库的佼佼者,因其强大的功能与性能被广泛应用于各种项目中。而 Python 则因其简洁易用的语法、丰富的库和强大的…

【2025年更新】1000个大数据/人工智能毕设选题推荐

文章目录 前言大数据/人工智能毕设选题:后记 前言 正值毕业季我看到很多同学都在为自己的毕业设计发愁 Maynor在网上搜集了1000个大数据的毕设选题,希望对大家有帮助~ 适合大数据毕业设计的项目,完全可以作为本科生当前较新的毕…

第十八章 视图

目录 一、概述 二、语法 2.1. 创建视图 2.2. 查询视图 2.3. 修改视图 2.4. 删除视图 2.5. 示例 三、检查选项 3.1. CASCADED(级联) 3.2. LOCAL(本地) 四、视图的更新 五、视图作用 5.1. 简单 5.2. 安全 5.3. 数据独…

2.1.3 相机图像信号处理的基本流程

文章目录 ISP基本流程ISP各基本流程职责 ISP基本流程 图像信号处理将传感器采集到的Bayer阵列数据转换成符合人眼观感的图像数据。ISP(Image Signal Processing)图像信号处理基本流程包括坏点校正(DPC, Defect Pixel Correction),黑电平校正&…

Android记事本App设计开发项目实战教程2025最新版Android Studio

平时上课录了个视频,从新建工程到打包Apk,从头做到尾,没有遗漏任何实现细节,欢迎学过Android基础的同学参加,如果你做过其他终端软件开发,也可以学习,快速上手Android基础开发。 Android记事本课…