📖 Spring 事务机制超详细讲解(哥们专属)
事务是后端开发中非常重要的一个概念,特别是在 Spring 框架里,事务管理直接关系到数据的正确性和一致性。
📖 Spring 事务超详细易懂教程
📌 什么是事务?
事务(Transaction)就是一组操作的集合,这组操作要么全部成功 ,要么全部失败,它是保证数据安全和一致性的重要机制。
例如:
在转账业务中:
- A 转给 B 100 块
👉 A 账户减少 100 元
👉 B 账户增加 100 元
如果中间某一步失败,就可能造成钱丢失或重复。这时候就需要事务。
📌 数据库事务的 4 大特性(ACID)
特性 | 全称 | 含义 |
---|---|---|
A | Atomicity(原子性) | 要么全做,要么全不做 |
C | Consistency(一致性) | 执行前后,数据必须符合一致性规则 |
I | Isolation(隔离性) | 多个事务相互隔离,互不干扰 |
D | Durability(持久性) | 事务提交后,数据永久保存 |
📌 Spring 为什么要做事务管理?
在 Java 中,操作数据库通常是:
- JDBC
- Hibernate
- MyBatis
每个框架都有自己的事务管理方式。Spring 统一管理事务,做到:
- 统一规范、统一方式
- 简化操作、配置灵活
- 脱离具体 ORM 框架,面向接口,松耦合
📌 Spring 事务的分类
✅ 编程式事务管理
在代码里手动写事务的开始、提交、回滚
scss
TransactionStatus status = transactionManager.getTransaction(definition);
try {
// 执行业务逻辑
transactionManager.commit(status); // 提交
} catch (Exception e) {
transactionManager.rollback(status); // 回滚
}
缺点:写法繁琐、容易出错。
✅ 声明式事务管理(🔥 常用)
不用写事务控制代码,只需要通过注解或配置声明,Spring 自动帮你管理事务。
👉 基于 @Transactional
注解(超常用)
示例
typescript
@Service
public class AccountService {
@Transactional
public void transfer(String from, String to, double amount) {
// A账户减钱
// B账户加钱
}
}
只要方法内抛出运行时异常,Spring 就会自动回滚事务!
📌 @Transactional 常见属性
属性 | 说明 | 常用值 |
---|---|---|
propagation |
事务传播行为 | REQUIRED 、REQUIRES_NEW |
isolation |
事务隔离级别 | READ_COMMITTED 、SERIALIZABLE |
timeout |
事务超时时间(秒) | 30 |
readOnly |
是否只读事务 | true/false |
rollbackFor |
指定遇到哪些异常回滚 | Exception.class |
📌 事务的传播行为(Propagation)
当一个方法在事务中被调用,如何处理事务?
传播行为 | 说明 |
---|---|
REQUIRED |
如果有事务,就加入当前事务,没有就新建 |
REQUIRES_NEW |
强制新建一个事务,暂停当前事务 |
NESTED |
如果当前有事务,就在事务内嵌套子事务 |
MANDATORY |
必须在已有事务中调用 |
NEVER |
不允许在事务中调用 |
SUPPORTS |
有事务就用,没有就不用 |
NOT_SUPPORTED |
永远不在事务中运行,挂起当前事务 |
最常用:REQUIRED
,REQUIRES_NEW
📌 事务的隔离级别(Isolation)
控制多个事务之间的可见性和访问顺序
隔离级别 | 含义 | 问题 |
---|---|---|
READ_UNCOMMITTED |
读未提交 | 脏读、不可重复读、幻读 |
READ_COMMITTED |
读已提交 | 不可重复读、幻读 |
REPEATABLE_READ |
可重复读 | 幻读 |
SERIALIZABLE |
串行化(最安全) | 无 |
默认:MySQL 是 REPEATABLE_READ
,Oracle 是 READ_COMMITTED
📌 事务失效的常见情况
- 同类方法内部调用,事务不起效
- 方法不是
public
,事务不起效 - 数据库不支持事务(如 MyISAM)
try-catch
吃掉异常,事务不会回滚@Transactional
放在接口上,未被代理
📌 实际项目中的用法
service 层加事务
- 方法粒度控制事务
- 配合 MyBatis/ JPA/ JDBC Template 使用
常见结构
typescript
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional
public void register(User user) {
userMapper.insertUser(user);
// 其他逻辑
}
}
异常回滚
- 默认:只回滚
RuntimeException
rollbackFor=Exception.class
指定回滚所有异常
📌 总结
概念 | 重点 |
---|---|
什么是事务 | 一组要么全部成功,要么全部失败的操作 |
ACID 特性 | 原子性、一致性、隔离性、持久性 |
Spring事务类型 | 编程式事务、声明式事务(@Transactional ) |
常用属性 | propagation 、isolation 、timeout 、readOnly |
事务失效原因 | 内部调用、非 public、数据库引擎等 |