一文详解MySQL中的事务和 MVCC 原理
本篇文章带大家了解一下MySQL中的事务,并介绍一下MVCC 原理,希望能够给大家提供帮助! 01 什么是事务? 数据库事务指的是一组数据操作,事务内的操作要么就是全部成功,要么就是
本篇文章带大家了解一下MySQL中的事务,并介绍一下MVCC 原理,希望能够给大家提供帮助!<p><img src="https://img.mryunwei.com/uploads/2023/04/20230416171500544.jpg"></p>
01 什么是事务?
数据库事务指的是一组数据操作,事务内的操作要么就是全部成功,要么就是全部失败,什么都不做,其实不是没做,是可能做了一部分但是只要有一步失败,就要回滚所有操作,有点一不做二不休的意思。
在 MySQL 中,事务支持是在引擎层实现的。MySQL 是一个支持多引擎的系统,但并不是所有的引擎都支持事务。比如 MySQL 原生的 MyISAM 引擎就不支持事务,这也是 MyISAM 被 InnoDB 取代的重要原因之一。
1.1 四大特性
SQL 事务的四大特性中原子性、一致性、持久性都比较好理解。但事务的隔离级别确实比较难的,今天主要聊聊 MySQL 事务的隔离性。
SQL 标准的事务隔离从低到高级别依次是:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(serializable )。级别越高,效率越低。
SQL 事务隔离级别的设计就是为了能最大限度的解决并发问题:
1.4 举个栗子
这么说可能有点难以理解,举个栗子。还是之前的表结构以及表数据
假设现在,我要同时启动两个食物,一个事务 A 查询 id = 2 的学生的 age,一个事务 B 更新 id = 2 的学生的 age。流程如下,在四种隔离级别下的 X1、X2、X3 的值分别是怎样的呢?
事务隔离级别是怎么是实现的呢?我在极客时间丁奇老师的课上找到了答案:
实际上,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在 “可重复读” 隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。在 “读提交” 隔离级别下,这个视图是在每个 SQL 语句开始执行的时候创建的。这里需要注意的是,“读未提交” 隔离级别下直接返回记录上的最新值,没有视图概念;而 “串行化” 隔离级别下直接用加锁的方式来避免并行访问。
1.5 设置事务隔离级别
不同的数据库默认设置的事务隔离级别也大不一样,Oracle 数据库的默认隔离级别是读提交,而 MySQL 是可重复读。所以,当你的系统需要把数据库从 Oracle 迁移到 MySQL 时,请把级别设置成与搬迁之前的(读提交)一致,避免出现不可预测的问题。
1.5.1 查看事务隔离级别
修改隔离级别语句格式是:set [作用域] transaction isolation level [事务隔离级别]
其中作用域可选:SESSION(会话)、GLOBAL(全局);隔离级别就是上面提到的 4 种,不区分大小写。
例如:设置全局隔离级别为读提交
MySQL 的事务启动有以下几种方式: