MySQL事务和Spring事务

一、数据库事务基础(MySQL)

1. 事务概念

事务是一组不可分割的数据库操作单元,单元内所有操作要么全部执行成功,要么全部执行失败,保证数据完整性。

2. MySQL 默认事务规则

MySQL 默认开启自动提交,每执行一条增删改(DML)语句,事务都会自动提交。

3. 典型使用场景

多表关联操作必须使用事务。例如新增员工时,需同时保存员工信息与工作经历,某一步出错则全部数据回滚,避免数据错乱。

4. MySQL 手动事务三步操作

完整流程:开启事务 → 执行业务SQL → 提交/回滚事务

  1. 开启事务
sql 复制代码
-- 两种写法任选其一
start transaction;
begin;
  1. 执行业务操作
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','阿里','架构');
  1. 结束事务
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() {
    // 业务逻辑
}

补充注意事项

  1. 开发规范:@Transactional 优先加在 Service 层,Controller 层不建议使用;
  2. 异常处理:默认不回滚受检异常,生产环境建议统一配置 rollbackFor = Exception.class
相关推荐
逍遥德1 小时前
PostgreSQL --- 数组函数详解
数据库·sql·postgresql
福大大架构师每日一题2 小时前
redis 8.8.0 发布:新数据结构、字段级通知、INCREX、XNACK 全面升级,8.6 到 8.8 变化一文看懂
数据结构·数据库·redis
霸道流氓气质2 小时前
Spring Data JPA 完全指南
开发语言·数据库
Demon1_Coder2 小时前
Day4-LangChain4j-向量数据库-检索增强RAG
数据库
phltxy2 小时前
RabbitMQ 应用问题
数据库·分布式·rabbitmq
星晨雪海2 小时前
基于 SpringBoot + Redis (Lettuce) + RabbitMQ 实现「Redis 预扣库存 + 异步同步数据库」
数据库·spring boot·java-rabbitmq
mosaic_born2 小时前
centos 7.9 离线部署Zabbix 6.0.46 监控详细方案(解决数据库字符集问题)
数据库·centos·zabbix
weelinking2 小时前
【产品】10_搭建前端框架——把你的原型变成真实页面
java·大数据·前端·数据库·人工智能·python·前端框架
会编程的土豆2 小时前
Go 里的 init() 到底是什么(彻底理解)
开发语言·后端·golang