MySQL事务完整入门笔记:从基础到并发隔离级别
前言
在开发业务系统时,转账、订单扣库存、支付回调这类场景绝对离不开事务。如果不使用事务,一旦程序中途崩溃,就会出现数据错乱、资金丢失等严重问题。本文结合课程目录,从零梳理 MySQL 事务全套知识点,包含实操、ACID、并发脏问题、四大隔离级别,适合 Java 后端初学者一次性吃透事务。
一、什么是事务(事务简介)
1. 事务定义
Transaction(事务)是一组不可分割的 SQL 操作单元,这一组操作要么全部执行成功,要么全部执行失败回滚,不存在中间状态。
2. 典型业务场景:转账
账户表account存在张三、李四两条数据,初始余额均为 1000。 需求:张三转给李四 1000 元,需要两条 SQL:
-- 1. 张三扣款 update account set money=money-1000 where name='张三'; -- 2. 李四加钱 update account set money=money+1000 where name='李四';如果不使用事务:第一条执行成功、第二条程序崩溃,张三钱被扣、李四没收到,数据出现永久性错误。 将两条 SQL 放进同一个事务,就能保证两条语句同时生效或同时撤销。
3. 引擎限制
MySQL 中只有InnoDB 引擎支持事务;MyISAM 引擎不支持事务,无法回滚。
二、事务基础操作演示
1. 核心开关:自动提交 autocommit
MySQL 默认autocommit=1(自动提交开启),每一条增删改语句执行后立刻永久入库,无法回滚。
-- 查看自动提交状态 select @@autocommit; -- 关闭自动提交,开启手动事务模式 set autocommit = 0;2. 事务两大核心指令
commit;提交事务:所有修改永久写入数据库,事务结束,无法回滚rollback;回滚事务:撤销当前事务内所有未提交修改,数据恢复原样
3. 完整实操示例
-- 关闭自动提交 set autocommit = 0; -- 转账操作 update account set money=money-1000 where name='张三'; update account set money=money+1000 where name='李四'; -- 确认无异常则提交 commit; -- 若出现异常,执行回滚撤销所有修改 -- rollback;实操坑点提醒
若先执行commit,事务已经结束,后续写rollback不会有任何效果,数据无法恢复。
三、事务四大核心特性 ACID
事务必须同时满足 4 个特性,简称 ACID,是面试高频考点:
原子性 Atomic事务是最小执行单元,不可拆分。一组操作要么全成功,要么全失败回滚。转账扣款和加钱一定同时生效 / 同时撤销。
一致性 Consistency事务执行前后,整体数据逻辑合法。转账前两人总余额 2000,事务结束后总余额依旧 2000,不会凭空多 / 少资金。
隔离性 Isolation多个事务并发操作同一张表时,事务之间互相隔离,每个事务看不到其他事务未提交的中间脏数据,避免并发错乱。
持久性 Durability一旦执行
commit提交事务,修改永久存入磁盘,服务器断电、重启、崩溃都不会丢失数据。
四、并发事务带来的三类数据问题
多用户同时操作数据库(并发事务)时,隔离性不足会产生三类异常,严重影响业务准确性:
1. 脏读 Dirty Read
事务 A 读取到事务 B 未提交、最终回滚作废的数据,读到虚假无效数据。 示例:事务 B 修改张三余额为 0 但未提交,事务 A 读到余额 0;随后 B 回滚,余额恢复 1000,A 拿到的 0 是脏数据。
2. 不可重复读 Non-Repeatable Read
同一个事务内,两次读取同一行数据,中间被其他事务修改并提交,两次查询结果不一致。 核心:同一行记录的值发生变化(update 操作)。 示例:事务 A 第一次查张三余额 1000;事务 B 扣款提交;A 再次查询余额变成 0,同一事务两次读数不同。
3. 幻读 Phantom Read
同一个事务内,两次相同条件批量查询,中间其他事务新增 / 删除数据并提交,两次查询行数不一致,像凭空多出 / 消失数据。 核心:符合条件的记录条数变化(insert/delete 操作)。 示例:事务 A 查询余额大于 0 的账户,查到 2 条;事务 B 新增王五账户并提交;A 再次查询得到 3 条,仿佛出现幻觉。
三者快速区分
脏读:读到别人回滚作废的未提交数据
不可重复读:同一行数据的值被修改
幻读:符合条件的记录行数增减
五、并发事务演示 & 四大隔离级别
MySQL 提供 4 种事务隔离级别,从低到高逐步解决脏读、不可重复读、幻读,隔离级别越高并发性能越差。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交 Read Uncommitted | 存在 | 存在 | 存在 |
读已提交 Read Committed(Oracle 默认) | 解决 | 存在 | 存在 |
可重复读 Repeatable Read(MySQL InnoDB 默认) | 解决 | 解决 | 存在 |
串行化 Serializable | 全部解决 | 全部解决 | 全部解决 |
各隔离级别说明
读未提交:性能最高,所有并发问题都存在,业务几乎不用。
读已提交:只能读取其他事务已提交的数据,杜绝脏读,但重复读、幻读依旧存在。
可重复读(MySQL 默认):同一个事务内多次读取数据,结果始终保持一致,解决脏读、不可重复读;仅存在幻读。依靠 MVCC 多版本并发控制实现。
串行化:最高隔离级别,所有事务串行排队执行,无并发冲突,三类问题全部消除,但并发性能极差,极少使用。
隔离级别操作命令
-- 查看当前会话隔离级别 select @@transaction_isolation; -- 设置会话隔离级别 set session transaction isolation level read committed;六、事务整体小结
事务核心作用:保证一组业务 SQL 操作原子执行,避免数据错乱,转账、库存、支付场景必备;
基础操作:关闭自动提交
set autocommit=0,commit提交、rollback回滚;四大特性 ACID:原子、一致、隔离、持久,是事务的标准规范;
并发三大问题:脏读、不可重复读、幻读,由事务并发引发;
四大隔离级别:逐级解决并发问题,MySQL 默认使用「可重复读」平衡性能与数据安全;
注意事项:DDL 语句(create/alter/drop)会强制自动提交当前事务,无法回滚。