MySQL 事务学习笔记:从 ACID 到隔离级别(含对照表) 一、事务的四大特性ACID事务可以把多条 SQL 打包成一个整体要么全部执行成功要么全部不生效。这里说的“全部不生效”并不是这些 SQL 真的没有执行而是通过回滚机制把数据恢复成最初的状态。事务具备四个基本特性简称ACID原子性Atomicity一个事务中的多条 SQL 是一个不可分割的整体要么全部执行成功要么全部回滚。一致性Consistency事务执行前和执行后数据库都必须满足约束和业务规则事务的执行不能破坏数据的完整性。例如转账前 AB1000转账后 AB 仍然等于 1000。隔离性Isolation一个数据库服务器可以同时处理多个客户端提交的事务这些事务之间互不干扰。持久性Durability事务对数据库做出的修改是持久的数据会被保存到硬盘上即使重启服务器或重启数据库数据也不会丢失。二、如何使用事务使用一个事务通常分为三步开启事务使用START TRANSACTION;。编写要打包执行的 SQL 语句。结束事务如果所有 SQL 都执行成功就提交如果出现问题就回滚。-- 开启事务 START TRANSACTION; -- 这里放置需要打包执行的 SQL 语句 -- 提交事务确认所有操作生效 COMMIT; -- 或者回滚事务撤销事务中的修改 ROLLBACK;三、保存点当一个事务内部要执行很多 SQL 时可以在中间设置一些保存点。如果后续某个操作失败不必回滚整个事务而可以回滚到前面某个指定的保存点。事务最终提交或者整体回滚后这些保存点就会消失。-- 设置保存点 SAVEPOINT sp1; -- 执行后续 SQL 语句 -- 回滚到指定保存点 ROLLBACK TO sp1; -- 释放保存点释放后不能再回滚到该保存点 RELEASE SAVEPOINT sp1;四、自动提交与手动提交MySQL 默认采用自动提交模式每执行一条 SQL 都会立即提交不需要手动写COMMIT。手动提交模式下SQL 执行后不会被立刻提交需要显式执行COMMIT或ROLLBACK来决定事务的结局。-- 开启自动提交 SET AUTOCOMMIT ON; -- 关闭自动提交切换为手动提交 SET AUTOCOMMIT OFF;如果仍想主动控制事务范围也可以使用START TRANSACTION;或BEGIN;开启一个事务。五、事务的隔离性与隔离级别首先要区分两个概念隔离性Isolation是 ACID 中的一个特性描述的是多个事务并发执行时彼此隔离、互不干扰的理想目标。隔离级别Isolation Level则是数据库为了在并发能力和数据准确性之间取得平衡提供的不同强度档位。简单来说隔离性是要达到的目标隔离级别是数据库提供的可配置强度选项。隔离级别越高并发度通常越低处理效率越低但数据准确性越高反之隔离级别越低并发度越高但一致性风险也越大。5.1 三个典型问题并发事务如果没有合理的隔离控制可能出现三种典型问题脏读事务 A 读到了事务 B 尚未提交的修改。如果事务 B 随后回滚事务 A 读到的就是“脏数据”。不可重复读同一个事务内两次读取同一行数据得到的结果不同。通常是因为两次读取之间其他事务提交了对这行数据的修改。幻读同一个事务内两次执行相同的范围查询得到的结果集行数不同。通常是因为其他事务在两次查询之间插入或删除了符合条件的记录。5.2 四个隔离级别MySQL 提供了四个由弱到强的隔离级别读未提交READ UNCOMMITTED最低隔离级别。脏读、不可重复读、幻读都可能发生。读已提交READ COMMITTED可以解决脏读但不可重复读和幻读仍可能发生。可重复读REPEATABLE READ可以解决脏读和不可重复读在 InnoDB 中通过 MVCC 和间隙锁等机制也能在很大程度上避免幻读。这是MySQL 的默认隔离级别。串行化SERIALIZABLE隔离性最强的级别事务几乎完全串行执行一个事务执行完才执行下一个从根本上解决幻读但并发能力最低。5.3 隔离级别与并发问题对照表隔离级别脏读不可重复读幻读说明读未提交READ UNCOMMITTED可能发生可能发生可能发生隔离性最弱读已提交READ COMMITTED已解决可能发生可能发生解决脏读可重复读REPEATABLE READ已解决已解决基本解决InnoDBMySQL 默认级别串行化SERIALIZABLE已解决已解决已解决隔离性最强并发最低总体建议如果偏向数据准确性可以选择较高级别如果读操作远多于写操作且能接受一定并发风险可以结合业务场景选择较低级别。MySQL 默认的可重复读在大多数场景下是比较均衡的选择。