MySQL 数据库事务

发布时间:2026/6/12 11:04:38

MySQL 数据库事务 一、事务基础1. 什么是事务事务Transaction是一组 SQL 语句的逻辑执行单元这组操作要么全部成功执行要么全部失败回滚不会出现部分执行、部分失败的中间状态。经典场景银行转账张三给李四转 100 元需要执行两个操作UPDATE bank_account SET balance balance - 100 WHERE name 张三;UPDATE bank_account SET balance balance 100 WHERE name 李四;这两个操作必须作为一个整体要么都成功要么都失败否则会出现张三余额减少但李四余额未增加的异常。2. 事务的核心目标在事务执行过程中必须保证以下四点即事务的ACID 特性原子性 (Atomicity)操作要么全成要么全败。一致性 (Consistency)事务前后数据的完整性不被破坏。隔离性 (Isolation)多个事务并发执行时互不干扰。持久性 (Durability)事务提交后数据修改永久保存到磁盘即使数据库崩溃也不会丢失。二、事务的 ACID 特性面试核心1. 原子性 (Atomicity)定义一个事务中的所有操作要么全部执行成功要么全部执行失败不会出现部分执行的情况。实现机制通过回滚 (Rollback)保证。如果事务执行过程中发生错误如服务器宕机、SQL 异常数据库会将数据恢复到事务开始前的状态就像这个事务从未执行过一样。关键操作ROLLBACK语句用于手动回滚事务。2. 一致性 (Consistency)定义事务执行前后数据库的完整性约束如数据总和、业务规则不会被破坏数据始终符合预期。例子转账前张三 李四余额总和是 2000转账后也必须是 2000900 1100不能变成 1900。实现机制数据库层面通过约束非空、唯一、外键等保证。故障恢复层面通过重做日志 (Redo Log)和回滚日志 (Undo Log)保证事务执行过程中服务器宕机后的数据一致性。3. 隔离性 (Isolation)定义多个并发事务同时对数据进行读写时彼此之间相互隔离一个事务的执行不会影响其他事务。核心问题并发事务会带来数据不一致问题需要通过隔离级别在安全性和性能之间做权衡。实现机制通过锁机制行锁、表锁和 MVCC多版本并发控制实现不同的隔离级别。4. 持久性 (Durability)定义事务一旦提交COMMIT对数据的修改就会永久保存到磁盘即使数据库服务器崩溃、操作系统崩溃或断电数据也不会丢失。实现机制事务提交时修改会先写入重做日志 (Redo Log)并持久化到磁盘。即使数据库宕机重启也会通过 Redo Log 恢复已提交的事务数据。三、事务的基本操作1. 查看支持事务的存储引擎SHOW ENGINES;InnoDBMySQL 默认存储引擎完整支持事务是生产环境的首选。MyISAM、MEMORY 等引擎不支持事务只适合只读场景。2. 事务控制语法2.1 开启事务-- 方式一标准语法 START TRANSACTION; -- 方式二简写与 START TRANSACTION 等价 BEGIN; -- 方式三BEGIN WORK与 BEGIN 等价 BEGIN WORK;开启事务后MySQL 会自动关闭自动提交 (autocommit)后续的修改操作需要手动COMMIT或ROLLBACK。2.2 提交事务-- 提交事务将修改永久保存到磁盘 COMMIT;提交后事务结束数据修改对其他事务可见。2.3 回滚事务-- 回滚事务撤销所有未提交的修改 ROLLBACK;回滚后事务结束数据恢复到事务开始前的状态。3. 自动提交与手动提交3.1 查看自动提交状态SHOW VARIABLES LIKE autocommit;ON默认值自动提交事务单条 DMLINSERT/UPDATE/DELETE执行后会自动提交。OFF手动提交所有修改必须显式调用COMMIT才会持久化。3.2 修改自动提交-- 开启自动提交 SET AUTOCOMMIT 1; -- 或 SET AUTOCOMMIT ON; -- 关闭自动提交 SET AUTOCOMMIT 0; -- 或 SET AUTOCOMMIT OFF;⚠️ 注意手动开启START TRANSACTION或BEGIN时会临时覆盖autocommit设置必须手动COMMIT/ROLLBACK结束事务。4. 保存点 (Savepoint)保存点用于在事务内部设置还原点可以将事务回滚到指定保存点而不是回滚整个事务。4.1 语法-- 1. 开启事务 START TRANSACTION; -- 2. 执行 SQL 操作... -- 3. 设置保存点 SAVEPOINT savepoint_name; -- 4. 继续执行 SQL 操作... -- 5. 回滚到指定保存点 ROLLBACK TO savepoint_name; -- 6. 提交或回滚整个事务 COMMIT; -- 或 ROLLBACK;4.2 示例START TRANSACTION; -- 操作1张三余额减100 UPDATE bank_account SET balance balance - 100 WHERE name 张三; SAVEPOINT sp1; -- 设置保存点sp1 -- 操作2李四余额加100 UPDATE bank_account SET balance balance 100 WHERE name 李四; SAVEPOINT sp2; -- 设置保存点sp2 -- 操作3新增王五账户 INSERT INTO bank_account VALUES (3, 王五, 5000); -- 回滚到sp1撤销操作2和操作3保留操作1 ROLLBACK TO sp1; COMMIT; -- 最终只保留张三余额减100的操作四、事务的隔离性与隔离级别1. 并发事务带来的问题多个事务并发执行时会出现以下三种数据不一致问题表格问题定义场景脏读 (Dirty Read)一个事务读取到了另一个事务未提交的数据事务 A 修改了数据但未提交事务 B 就读到了这个修改值若 A 回滚B 读到的数据就是脏数据不可重复读 (Non-repeatable Read)同一个事务内两次相同条件查询得到的结果不一致事务 A 第一次查询得到数据 X事务 B 修改了 X 并提交事务 A 再次查询得到了不同的数据幻读 (Phantom Read)同一个事务内两次范围查询得到的记录数不一致事务 A 第一次查询得到 10 条记录事务 B 插入了新记录并提交事务 A 再次查询得到 11 条记录2. 四种隔离级别MySQL InnoDB 支持四种隔离级别从低到高依次为表格隔离级别脏读不可重复读幻读特点READ UNCOMMITTED (读未提交)❌ 存在❌ 存在❌ 存在隔离性最低性能最高几乎不用READ COMMITTED (读已提交)✅ 解决❌ 存在❌ 存在Oracle、SQL Server 默认级别避免脏读REPEATABLE READ (可重复读)✅ 解决✅ 解决⚠️ 部分解决MySQL InnoDB 默认级别通过 MVCC 解决不可重复读通过 Next-Key Lock 解决大部分幻读SERIALIZABLE (串行化)✅ 解决✅ 解决✅ 解决隔离性最高性能最差完全串行执行避免所有并发问题3. 隔离级别详解3.1 READ UNCOMMITTED读未提交问题允许事务读取其他事务未提交的数据会出现脏读、不可重复读、幻读。场景几乎不使用仅用于理论演示。3.2 READ COMMITTED读已提交解决脏读事务只能读取其他事务已提交的数据。存在不可重复读、幻读。设置语句SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;3.3 REPEATABLE READ可重复读解决脏读、不可重复读同一个事务内多次查询结果一致。存在部分幻读MySQL 通过Next-Key Lock间隙锁 行锁机制在一定程度上避免了幻读。设置语句SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;核心实现InnoDB 的 MVCC多版本并发控制为每个事务生成数据快照保证事务期间读到的数据是一致的。3.4 SERIALIZABLE串行化解决所有并发问题强制事务串行执行完全避免竞争。缺点性能极差并发能力几乎为零仅用于对数据一致性要求极高的场景如金融核心系统。设置语句SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;4. 查看与设置隔离级别4.1 查看当前隔离级别-- 查看全局隔离级别 SELECT GLOBAL.transaction_isolation; -- 查看当前会话隔离级别 SELECT SESSION.transaction_isolation;4.2 设置隔离级别-- 方式一设置全局所有新连接生效 SET GLOBAL TRANSACTION ISOLATION LEVEL [LEVEL]; -- 方式二设置当前会话仅当前连接生效 SET SESSION TRANSACTION ISOLATION LEVEL [LEVEL];[LEVEL]可替换为READ UNCOMMITTED/READ COMMITTED/REPEATABLE READ/SERIALIZABLE五、事务的底层实现补充1. MVCC多版本并发控制作用在REPEATABLE READ隔离级别下实现读写不阻塞提升并发性能。原理为每行数据保存多个版本事务读取时选择合适的版本快照。通过undo log保存历史版本通过read view决定可见版本。优势读操作不加锁写操作只加行锁大幅提升并发读写性能。2. 锁机制行锁 (Row Lock)锁定单行数据并发粒度最小性能最高。间隙锁 (Gap Lock)锁定索引间隙防止其他事务在间隙中插入数据避免幻读。Next-Key Lock行锁 间隙锁是 InnoDB 在REPEATABLE READ隔离级别下避免幻读的核心手段。表锁 (Table Lock)锁定整张表并发粒度最大性能最差仅用于 DDL 操作。六、事务使用最佳实践事务要短小避免长事务如事务执行时间超过几秒长事务会占用锁资源导致其他事务阻塞甚至引发死锁。避免在事务中执行无关操作如网络请求、IO 操作这些操作会延长事务执行时间增加锁竞争。选择合适的隔离级别普通业务使用 MySQL 默认的REPEATABLE READ。对一致性要求极高的金融场景可考虑SERIALIZABLE。读多写少、对一致性要求不高的场景可使用READ COMMITTED提升性能。显式控制事务边界不要依赖autocommit在业务代码中显式使用BEGIN/COMMIT/ROLLBACK保证事务逻辑清晰。谨慎使用保存点保存点会增加事务复杂度仅在需要部分回滚的场景下使用。处理事务异常在代码中捕获异常异常发生时必须ROLLBACK避免数据不一致。七、事务面试高频考点事务的 ACID 特性是什么分别怎么实现并发事务会带来哪些问题对应的隔离级别是什么MySQL InnoDB 默认的隔离级别是什么怎么解决幻读什么是 MVCC它的作用是什么什么是脏读、不可重复读、幻读分别怎么解决事务的提交和回滚有什么区别什么是自动提交如何关闭自动提交

相关新闻