Mysql——事务隔离

本文深入探讨了数据库事务的ACID属性,并解析了在不同隔离级别下(读未提交、读提交、可重复读、串行化)可能出现的问题及行为。通过实例展示了这些隔离级别如何影响事务间的可见性,强调了在效率与安全性之间找到平衡的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mysql——事务隔离

内容出自丁奇45讲
提到事物肯定就要提到ACID
A:Atomicity 原子性
C:Consistency 一致性
I:IsoLation 隔离性
D:Durability 持久性

当数据库有多个数据执行的时候,就可能会出现脏读不可重复读幻读的问题为了解决这样的问题,就有了“隔离级别”的概念

脏读:在执行事务A的时候,读取到了事务B未提交的数据,之后事务B发生了回滚,事务A读到了脏的数据

不可重复读:在同一个事务中读同一个字段,内容一不一样,比如说事务A内执行Select age from A,第一次执行获得的年龄是18,然后事务B对年龄进行了更改将年龄改成了20,再后面事务A再执行Select age from A的语句,读到的年龄不为18,而是20,前后多次读取,数据内容不一致

幻读:在同一个事务中读一个表某个数据的行总量,两次读取的行数不一样,比如说事务A执行Select count() from A,第一次读到的行数是100行,然后其他事务对这个表进行了修改,行数发生了变化,之后事务A再执行Select count() from A,前后多次读取,表的行数不一致

不理解的同学们可以再看一看这个博主的文章,十分的详细https://blog.youkuaiyun.com/qq_33591903/article/details/81672260

在谈隔离级别之前,你首先要知道,你隔离得越严实,效率就会越低。因此很多时候,我们都要在二者之间寻找一个平衡点。SQL标准的事务隔离级别包括:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(serializable )。下面我逐一为你解释:

  • 读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。
  • 读提交是指,一个事务提交之后,它做的变更才会被其他事务看到。
  • 可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。
  • 串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

其中“读提交”和“可重复读”比较难理解,所以我用一个例子说明这几种隔离级别。假设数据表T中只有一列,其中一行的值为1,下面是按照时间顺序执行两个事务的行为。

mysql> create table T(c int) engine=InnoDB;
insert into T(c) values(1);

img
我们来看看在不同的隔离级别下,事务A会有哪些不同的返回结果,也就是图里面V1、V2、V3的返回值分别是什么。

  • 若隔离级别是“读未提交”, 则V1的值就是2。这时候事务B虽然还没有提交,但是结果已经被A看到了。因此,V2、V3也都是2。
  • 若隔离级别是“读提交”,则V1是1,V2的值是2。事务B的更新在提交后才能被A看到。所以, V3的值也是2。
  • 若隔离级别是“可重复读”,则V1、V2是1,V3是2。之所以V2还是1,遵循的就是这个要求:事务在执行期间看到的数据前后必须是一致的。
  • 若隔离级别是“串行化”,则在事务B执行“将1改成2”的时候,会被锁住。直到事务A提交后,事务B才可以继续执行。所以从A的角度看, V1、V2值是1,V3的值是2。

事务B才可以继续执行。所以从A的角度看, V1、V2值是1,V3的值是2。

在实现上,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。在“读提交”隔离级别下,这个视图是在每个SQL语句开始执行的时候创建的。这里需要注意的是,“读未提交”隔离级别下直接返回记录上的最新值,没有视图概念;而“串行化”隔离级别下直接用加锁的方式来避免并行访问。

本内容用于自身学习,内容出自丁奇45讲

### MySQL 事务隔离级别面试常见问题及解答 #### 常见问题一:什么是MySQL中的事务事务是指访问并可能更新各种数据项的一个程序执行单元。为了保证数据的一致性和可靠性,事务具有四个特性:原子性(Atomicity),一致性(Consistency),隔离性(Isolation)以及持久性(Durability)[^1]。 #### 常见问题二:MySQL支持哪些事务隔离级别?默认的是哪一个? MySQL 支持四种标准的事务隔离级别: - **读未提交 (Read Uncommitted)**:允许脏读取,即一个事务可以读到另一个尚未提交的事务修改过的数据。 - **读已提交 (Read Committed)**:只允许读取已经提交的数据,防止了脏读取的发生。 - **可重复读 (Repeatable Read)**:这是 MySQL 的默认隔离级别[^2];在此模式下,只要某个字段被锁定,则其他任何事务都不能对该字段进行更改直到当前事务结束。 - **序化 (Serializable)**:提供最高级别的隔离度,通过强制事务串行执行来避免幻读现象。 #### 常见问题三:解释一下“不可重复读”和“幻读”的区别是什么? - 幻读则是指当同一个事务两次查询相同范围内的记录时出现了不同的集合大小变化情况,这通常是由于其他事务插入新纪录所引起的。在 `REPEATABLE READ` 下虽然解决了前者的问题但是后者仍然可能存在[^1]。 ```sql -- 设置会话级隔离级别为 SERIALIZABLE SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; ``` #### 常见问题四:如何设置全局/会话级别的事务隔离等级? 可以通过如下 SQL 来改变整个服务器上的所有连接或者是单个客户端连接使用的隔离水平: 对于全局配置: ```sql SET GLOBAL TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}; ``` 针对特定会话: ```sql SET SESSION TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}; ``` #### 常见问题五:为什么有时候即使设置了较高的隔离级别也无法达到预期效果? 如果应用程序逻辑设计不当或者存在某些特殊场景下的竞争条件(race condition),那么即便是在高隔离级别之下也可能无法完全杜绝异常行为的发生。此外需要注意的是,并不是所有的存储引擎都支持全部类型的隔离机制——例如 MyISAM 就不支持真正的事务处理功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值