玉环市建设规划局网站网络营销环境宏观微观分析
一、MySQL事务
MySQL 中的 事务(Transaction) 是一种将多个 SQL 操作打包成一个整体执行的机制,确保数据的一致性和可靠性。事务广泛用于需要原子性的数据操作,比如转账、订单创建等。
事务的四大特性(ACID):
| 特性 | 说明 | 
|---|---|
| 原子性(Atomicity) | 一个事务中的操作要么全部成功,要么全部失败,不可分割。 | 
| 一致性(Consistency) | 事务执行前后,数据库处于一致状态(遵守约束规则、业务规则)。 | 
| 隔离性(Isolation) | 多个事务互不干扰,彼此隔离。事务并发时数据仍一致。 | 
| 持久性(Durability) | 一旦事务提交,修改永久保存,即使系统崩溃也不会丢失。 | 
二、事务基本语句
事务基本语句(InnoDB 引擎支持事务):
| 语句 | 作用 | 
|---|---|
START TRANSACTION; 或 BEGIN; | 显式开始一个事务 | 
COMMIT; | 提交事务,永久保存所有操作 | 
ROLLBACK; | 回滚事务,撤销所有操作 | 
SAVEPOINT 保存点名; | 设置一个保存点,用于部分回滚 | 
ROLLBACK TO 保存点名; | 回滚到某个保存点,仅撤销一部分操作 | 
SET autocommit = 0; | 关闭自动提交,进入手动事务控制状态 | 
SET autocommit = 1; | 恢复自动提交(默认) | 
注意:
 MySQL 默认是自动提交模式,即每条语句自动提交。
示例一:基本事务流程
START TRANSACTION;UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;COMMIT;
 
如中途出错,也可用:
ROLLBACK;
 
示例二:使用保存点(SAVEPOINT)
 
START TRANSACTION;UPDATE users SET score = score + 10 WHERE id = 1;SAVEPOINT sp1;UPDATE users SET score = score - 50 WHERE id = 2;ROLLBACK TO sp1;COMMIT;
 
注意:
- 第二条 
UPDATE被撤销,第一条仍然生效。 
三、事务隔离级别(Isolation Level)
事务隔离级别定义了一个事务能看到其他事务对数据库的更改程度。
| 级别 | 可解决的问题 | 会出现的问题 | MySQL默认 | 
|---|---|---|---|
| READ UNCOMMITTED | 无 | 会出现脏读 | ❌ | 
| READ COMMITTED | 解决脏读 | 可能出现不可重复读 | ❌ | 
| REPEATABLE READ (默认) | 解决脏读和不可重复读 | 可能出现幻读 | ✅ | 
| SERIALIZABLE | 解决所有问题(脏读、不可重复读、幻读) | 并发性能差 | ❌ | 
设置事务隔离级别:
SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL REPEATABLE READ;
 
四、事务中的日志机制
| 日志类型 | 作用 | 
|---|---|
Undo Log | 撤销未提交的事务、实现 MVCC | 
Redo Log | 保证事务提交后数据的持久性 | 
Binlog | 用于主从复制、增量备份 | 
InnoDB 使用 “先写日志、后写磁盘” 策略,避免崩溃丢数据。
五、事务引擎:InnoDB
MySQL 中支持事务的主要引擎是 InnoDB,它是 MySQL 的默认存储引擎,也是最常用于高可靠性、高并发场景的引擎。
1. InnoDB 引擎简介
| 特性 | 是否支持 | 说明 | 
|---|---|---|
| 支持事务(ACID) | ✅ | 完整支持事务四大特性 | 
| 行级锁定 | ✅ | 并发控制粒度细,避免表级锁带来的性能问题 | 
| 外键约束 | ✅ | 支持 FOREIGN KEY 语法进行引用完整性约束 | 
| 自动崩溃恢复 | ✅ | 通过 Redo Log(重做日志) 和 Undo Log(回滚日志) 实现 | 
| 多版本并发控制(MVCC) | ✅ | 实现高并发下的非阻塞读操作 | 
| 支持全文索引 | ✅(5.6+) | 支持 FULLTEXT 索引,适用于文本搜索 | 
| 表空间管理 | ✅ | 支持独立表空间 (innodb_file_per_table) | 
2. InnoDB 事务核心机制
InnoDB 通过以下几项核心机制实现高可靠事务性:
(1) Undo Log(回滚日志)
 
- 在数据修改前记录一份旧值(用于回滚或 MVCC)。
 - 保证事务回滚和一致性视图。
 - 存储在 
undo segment中,自动清理。 
(2)Redo Log(重做日志)
 
- 记录已提交事务对数据的修改操作。
 - 用于 崩溃恢复,防止宕机后数据丢失。
 - 先写日志再写磁盘(WAL:Write-Ahead Logging)。
 - 由 
ib_logfile0/1或#innodb_redo文件组成。 
(3)MVCC(多版本并发控制)
 
- 实现 
快照读,避免加锁,提高读性能。 - 每条记录有隐藏的事务ID和回滚指针。
 - 只有 
REPEATABLE READ和READ COMMITTED使用 MVCC。 
3. 事务隔离级别(Isolation Level)
InnoDB 支持 SQL 标准的 4 种隔离级别:
| 隔离级别 | 是否支持脏读 | 是否支持不可重复读 | 是否支持幻读 | InnoDB 默认 | 
|---|---|---|---|---|
READ UNCOMMITTED | ✅ | ✅ | ✅ | 否 | 
READ COMMITTED | ❌ | ✅ | ✅ | 否 | 
REPEATABLE READ | ❌ | ❌ | ✅ | ✅ 默认 | 
SERIALIZABLE | ❌ | ❌ | ❌ | 否 | 
💡 InnoDB 通过 间隙锁(Gap Lock) 解决幻读,而不是真正序列化。
六、事务并发问题
| 并发问题 | 描述 | 影响隔离级别 | 
|---|---|---|
| 脏读 | 读到未提交事务的数据 | 仅 SERIALIZABLE & REPEATABLE READ 避免 | 
| 不可重复读 | 两次查询同一记录,结果不同(别的事务修改了数据) | REPEATABLE READ 能避免 | 
| 幻读 | 两次查询满足条件的记录数不同(别的事务插入了新数据) | SERIALIZABLE 避免 | 
七、典型示例——银行转账事务
START TRANSACTION;UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;-- 出错则回滚
-- IF (error) THEN
--     ROLLBACK;
-- ELSE
COMMIT;
 
注意:
- 如果两个 
UPDATE都成功执行,则COMMIT,数据写入磁盘; - 如果任一语句执行失败(例如账户不存在、余额不足等),应手动调用 
ROLLBACK撤销所有操作。 
八、两阶段提交(事务+Binlog)
 
InnoDB 为保证与 Binlog 一致,使用两阶段提交机制(prepare → commit):
- 写 
Redo Logprepare; - 写 
Binlog; Redo Logcommit;
保证主从一致性,避免部分提交。
九、MySQL事务常见问题与答案
| 问题 | 简要答案 | 
|---|---|
| InnoDB 如何保证事务原子性? | Undo Log 记录原始版本,失败时可回滚 | 
| 如何防止脏读? | 设置隔离级别为 READ COMMITTED 或更高 | 
| 什么是幻读?怎么解决? | 并发插入导致结果数量变化,使用 Gap Lock / SERIALIZABLE 隔离级别 | 
Redo Log 和 Binlog 有何不同? | Redo 是物理日志用于崩溃恢复;Binlog 是逻辑日志用于复制与备份 | 
