
一、事务简介1. 什么是事务事务是一组 DML 操作的集合是不可分割的最小工作单元。 事务会将集合内所有操作作为整体向数据库提交 / 撤销集合内操作要么同时全部成功要么同时全部失败。2. 事务默认规则MySQL 默认自动提交事务执行一条 DML 语句就自动提交一次事务。 如果业务中途出现异常需要手动回滚事务保证数据一致性。3. 事务标准执行流程plaintext开启事务 → 执行步骤1 → 执行步骤2 → 执行步骤3 → 无异常提交事务 / 出现异常回滚事务二、事务实操转账案例1. 数据准备 SQLsql-- 创建账户表 create table account( id int auto_increment primary key comment 主键ID, name varchar(10) comment 姓名, money int comment 余额 ) comment 账户表; -- 初始化测试数据张三、李四各2000元 insert into account(id, name, money) VALUES (null,张三,2000),(null,李四,2000); -- 恢复测试数据每次测试前重置余额 update account set money 2000 where name 张三 or name 李四;2. 转账业务需求张三给李四转账 1000 元分 3 步查询张三账户余额张三余额减少 1000李四余额增加 10002.1 无事务控制存在数据安全隐患如果第二步执行后程序抛出异常第三条更新语句不会执行会出现张三钱减少、李四钱未增加的数据错乱。sql-- 1. 查询张三账户余额 select * from account where name 张三; -- 2. 将张三账户余额-1000 update account set money money - 1000 where name 张三; -- 模拟程序异常中断代码执行 -- 程序抛出异常 -- 3. 将李四账户余额1000异常后不会执行 update account set money money 1000 where name 李四;2.2 手动开启事务完整示例sql-- 开启事务 START TRANSACTION; -- 1. 查询张三账户余额 select * from account where name 张三; -- 2. 张三扣1000 update account set money money - 1000 where name 张三; -- 模拟程序异常 -- 程序抛出异常 -- 3. 李四加1000 update account set money money 1000 where name 李四; -- 无异常则提交事务永久生效 COMMIT; -- 出现异常则回滚事务所有操作全部撤销 ROLLBACK;三、事务两种控制方式方式 1修改自动提交参数autocommit查看当前自动提交状态sqlSELECT autocommit; -- 返回1开启自动提交MySQL默认 -- 返回0关闭自动提交关闭自动提交后续 DML 需要手动 commitsqlSET autocommit 0;手动提交 / 回滚sqlCOMMIT; -- 提交事务数据永久保存 ROLLBACK;-- 回滚事务撤销所有未提交操作方式 2START TRANSACTION显式开启事务推荐业务开发使用仅当前代码块生效不修改全局自动提交配置sql-- 开启事务 START TRANSACTION; -- 业务DML操作... COMMIT; -- 正常提交 ROLLBACK;-- 异常回滚四、事务四大特性 ACID原子性Atomicity事务是不可分割的最小操作单元内部操作要么全部成功要么全部失败。一致性Consistency事务执行前后数据库整体数据约束保持一致转账总金额不变。隔离性Isolation并发执行的多个事务之间互相隔离互不干扰。持久性Durability事务一旦执行COMMIT提交对数据的修改永久保存到磁盘宕机也不会丢失回滚则完全撤销修改。五、并发事务三大问题多事务同时操作同一张表时会出现三类数据问题由隔离级别控制解决脏读一个事务读到了另一个事务未提交的修改数据。若对方事务回滚读到的数据就是无效脏数据。不可重复读同一个事务内两次读取同一行数据中间被其他事务修改并提交两次查询结果不一致。幻读同一个事务内按条件查询无数据插入数据时报主键冲突因为其他事务已插入同条件数据像出现 “幻影” 行。六、事务四大隔离级别隔离级别从低到高隔离性越强并发性能越低安全性越高。表格隔离级别脏读不可重复读幻读READ UNCOMMITTED读未提交存在存在存在READ COMMITTED读已提交解决存在存在REPEATABLE READ可重复读MySQL 默认解决解决存在SERIALIZABLE串行化解决解决解决1. 查看当前事务隔离级别sqlSELECT TRANSACTION_ISOLATION;2. 设置事务隔离级别语法sql-- SESSION仅当前会话生效GLOBAL全局所有客户端永久生效 SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}3. 各隔离级别设置示例sql-- 1. 读未提交允许脏读 set session transaction isolation level read uncommitted; -- 2. 读已提交解决脏读Oracle默认 set session transaction isolation level read committed; -- 3. 可重复读MySQL InnoDB默认解决脏读、不可重复读 set session transaction isolation level repeatable read; -- 4. 串行化最高安全性能最差完全串行执行 set session transaction isolation level serializable;核心结论事务隔离级别越高数据并发安全性越强但数据库并发性能越低开发中一般使用默认REPEATABLE READ。七、总结事务是一组 DML 操作集合核心目标要么全部成功要么全部失败保证数据安全事务操作核心命令START TRANSACTION开启、COMMIT提交、ROLLBACK回滚事务四大核心特性原子性、一致性、隔离性、持久性ACID并发事务三类问题脏读、不可重复读、幻读四级隔离级别读未提交、读已提交、可重复读、串行化安全递增、性能递减。