# MySQL事务

> 来源：梦飞idc云平台 | 原文：https://www.mfisp.com/9714.html | 发布：2022-09-06 | 更新：2022-09-06 | 分类：建站教程、投稿分享

### 1 事务特性

 

ACID四大特性：

 
 
- 原子性 (atomicity)

 

事务中的所有操作要么全部执行成功，要么会退到事务之前的状态 
- 一致性 (consistency)

 

一致性状态下，所有事务对同一个数据的读取结果是相同的 
- 隔离性 (isolation)

 

一个事务的影响范围在提交前对其他事务不可见(锁机制) 
- 持久性 (durability)

 

事务一旦提交，即可持久化到磁盘，可进行宕机恢复 

 

### 2 事务实现

 

#### 2.1 redo

 

在InnoDB存储引擎中，事务日志通过重做日志(redo log)和日志缓冲(Log Buffer)实现，

 
 
- 开启事务，记录事务的序列号 
- 事务执行时，往日志缓冲插入事务日志 
- 事务提交，缓冲区日志写入磁盘 
- mysql> show engine innodb status\G;  
---  
LOG  
---  
#表示当前的LSN  
Log sequence number 2713307  
#表示刷新到重做日志的LSN  
Log flushed up to 2713307  
Pages flushed up to 2713307  
#表示刷新到磁盘的LSN  
Last checkpoint at 2713298  
Max checkpoint age 1736863212  
Checkpoint age target 1682586237  
Modified age 0  
Checkpoint age 9  
0 pending log flushes, 0 pending chkp writes  
85 log i/o's done, 0.00 log i/o's/second

 

注：生产环境中三个LSN的值可能是不一致的

 

#### 2.2 undo

 

重做日志记录了事务的行为，可以对其进行重做，但事务撤销回滚需要用到undo。不同的是，redo存放在重做日志文件中，而undo放在数据库内部的一个特殊段，称为undo段，位于共享表空间中

 

当事务执行roll back时，会将插入的事务进行回滚，反向执行事务的操作，回滚或执行完事务后undo日志存放的表空间不会立即释放，需等待master线程进行回收

 

### 3 事务控制

 

事务开启需指定事务控制语句，或禁用自动提交

 

事务控制语句：

 
 
  - START TRANSACTION|BEGIN：显式地开启一个事务 
  - COMMIT：提交事务 
  - ROLLBACK：回滚结束的事务 
  - SAVEPOINT identifier：允许在事务创建保存点，一个事务可以有多个point 
  - RELEASE SAVEPOINT identifier：删除一个事务的保存点 
  - ROLLBACK TO [SAVEPOINT] identifier：与SAVEPOINT搭配使用，可以将事务回滚到标记点，不能结束事务，结束仍需执行commit或者rollback 
  - SET TRANSACTION：设置事务的隔离级别 

 

在MySQL命令行下可用begin语句显式的开启一个事务，但在存储过程中，只能用START TRANSACTION开启事务

 

隐式提交的SQL语句

 
 
  - DDL语句：数据库、数据表操作语句 
  - 用户与权限：用户以及权限的创建删除 
  - 管理语句：创建索引、分析表、优化表 

 

### 3 事务的隔离级别

 

SQL标准定义的四种隔离级别：

 
 
  - READ UNCOMMITTED (读未提交) 
  - READ COMMITTED (RC 读已提交)

 

Replication需运行在二进制日志ROW格式下，避免缺少间隙锁导致数据同步不一致的问题 
  - REPEATABLE READ (RR 可重复读 默认)

 

通过Next-Key Lock锁，避免幻读产生 
  - SERIALIZABLE (序列化) 

 

注：上述隔离级别从低到高排列，隔离级别越低，事务请求的锁越少

 

**脏读(Drity Read)：**某个事务已更新一份数据，另一个事务在此时读取了同一份数据，由于某些原因，前一个RollBack了操作，则后一个事务所读取的数据就会是不正确的

 

**不可重复读(Non-repeatable read)：**在一个事务的两次查询之中数据不一致，这可能是两次查询过程中间插入了一个事务更新的原有的数据

 

**幻读(Phantom Read)：**在一个事务的两次查询中数据笔数不一致，例如有一个事务查询了几列(Row)数据，而另一个事务却在此时插入了新的几列数据，先前的事务在接下来的查询中，就会发现有几列数据是它先前所没有的 
- ### 4 分布式事务

 

InnoDB支持XA事务，通过XA事务可支持分布式事务实现，分布式事务常用于银行的转账系统

 

分布式事务由一个或多个资源管理器、事务管理器以及应用程序组成

 
 
  - 资源管理器：提供访问事务的方法 
  - 事务管理器：协调参与全局事务的各个事务 
  - 应用程序：定义事务的边界，指定全局事务中的操作 

 

附：

 

为什么企业里不使用MySQL默认的可重复读，而使用读已提交？

 

1、老版本的MySQL的binlog只支持STATEMENT格式，该格式在读已提交下主从复制存在bug，于是MySQL默认使用可重复读作为默认隔离级别

 

2、RR级别下存在间隙锁，而RC下不存在，出现死锁的几率降低

 

3、RC级别下，半一致读特性增加了对update操作的并发性

 

4、现阶段RC级别的binlog支持row格式基于行的复制同步

 

![MySQL事务](https://www.mfisp.com/wp-content/uploads/2022/01/1341ee10c736eb8_1_post.jpg)

---
本页由 梦飞idc云平台（https://www.mfisp.com）提供。站点导航见 https://www.mfisp.com/llms.txt
