一、数据库事务基础(MySQL)
1. 事务概念
事务是一组不可分割的数据库操作单元,单元内所有操作要么全部执行成功,要么全部执行失败,保证数据完整性。
2. MySQL 默认事务规则
MySQL 默认开启自动提交,每执行一条增删改(DML)语句,事务都会自动提交。
3. 典型使用场景
多表关联操作必须使用事务。例如新增员工时,需同时保存员工信息与工作经历,某一步出错则全部数据回滚,避免数据错乱。
4. MySQL 手动事务三步操作
完整流程:开启事务 → 执行业务SQL → 提交/回滚事务
- 开启事务
sql
-- 两种写法任选其一
start transaction;
begin;
- 执行业务操作
sql
-- 新增员工基础信息
insert into emp values (39, 'Tom', '123456', '汤姆', 1, '13300001111', 1, 4000, '1.jpg', '2023-11-01', 1, now(), now());
-- 批量新增该员工工作经历
insert into emp_expr(emp_id, begin, end, company, job)
values (39,'2019-01-01','2020-01-01','百度','开发'),
(39,'2020-01-10','2022-02-01','阿里','架构');
- 结束事务
sql
commit; -- 执行正常,提交事务,数据永久生效
rollback;-- 出现异常,回滚事务,数据恢复至操作前状态
二、事务四大特性(ACID)
事务四大核心特性,简称 ACID:
| 特性 | 英文 | 核心说明 |
|---|---|---|
| 原子性 | Atomicity | 事务不可拆分,所有操作全部成功或全部失败 |
| 一致性 | Consistency | 事务执行前后,数据库数据状态保持合法一致 |
| 隔离性 | Isolation | 并发多个事务相互隔离,互不干扰 |
| 持久性 | Durability | 事务提交/回滚后,数据变更永久保存,不受系统故障影响 |
三、Spring 声明式事务
Spring 对原生事务进行封装,通过注解快速实现事务管理,开发中主流使用声明式事务。
1. 核心注解:@Transactional
作用
注解修饰的方法/类由 Spring 自动管理事务:
- 方法执行前:自动开启事务
- 方法正常结束:自动提交事务
- 方法抛出异常:自动回滚事务
使用位置
优先级:方法 > 类 > 接口,推荐添加在业务层(Service)方法上。
代码示例
java
@Transactional
@Override
public void save(Emp emp) {
// 补全基础字段
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
// 保存员工基础信息
empMapper.insert(emp);
// 模拟运行时异常,测试事务回滚
// int i = 1 / 0;
// 批量保存员工工作经历
Integer empId = emp.getId();
List<EmpExpr> exprList = null;
// 批量插入逻辑...
}
2. 事务日志配置
如需查看事务执行流程,在 application.yml 配置日志级别:
yaml
logging:
level:
# 开启Spring事务管理器Debug日志
org.springframework.jdbc.support.JdbcTransactionManager: debug
四、Spring 事务进阶配置
1. rollbackFor:异常回滚规则
默认规则
Spring 事务仅对运行时异常(RuntimeException)触发回滚,受检异常不会回滚。
自定义规则
通过 rollbackFor 指定需要回滚的异常类型,常用配置:所有异常均触发回滚。
java
@Transactional(rollbackFor = {Exception.class})
@Override
public void save(Emp emp) {
// 业务逻辑
}
2. propagation:事务传播行为
概念
当一个事务方法调用另一个事务方法时,被调用方法的事务沿用规则,即为事务传播行为。
常用传播行为
| 属性值 | 含义 |
|---|---|
| REQUIRED(默认) | 当前有事务则加入,无事务则新建事务 |
| REQUIRES_NEW | 始终创建全新独立事务 |
| SUPPORTS | 有事务就加入,无事务则非事务运行 |
| NOT_SUPPORTED | 始终以非事务方式运行,挂起原有事务 |
| MANDATORY | 强制在事务内运行,无事务直接抛异常 |
| NEVER | 强制非事务环境运行,存在事务直接抛异常 |
代码示例
java
import org.springframework.transaction.annotation.Propagation;
@Transactional(propagation = Propagation.REQUIRED)
public void b() {
// 业务逻辑
}
补充注意事项
- 开发规范:
@Transactional优先加在 Service 层,Controller 层不建议使用; - 异常处理:默认不回滚受检异常,生产环境建议统一配置
rollbackFor = Exception.class。