Spring 中事务可以分为声明式事务和编程式事务,那么解下来就从这两方面说一说在 Spring 层面个怎么进行回滚
声明式事务回滚:
1. 基础注解配置
通过@Transactional注解实现自动回滚,默认对RuntimeException和Error生效
@Transactional
public void transferMoney(Account from, Account to, double amount) {
from.withdraw(amount); // 扣款
to.deposit(amount); // 存款
// 若在此处抛出RuntimeException,事务自动回滚
}
2. 指定回滚异常类型
可以通过 @Transactional 注解的 rollbackFor 参数扩展回滚范围到受检异常
@Transactional(rollbackFor = {SQLException.class, BusinessException.class})
public void processOrder(Order order) throws CustomException {
// 抛出SQLException或BusinessException时回滚
}
需要显示声明受检查异常类型,否则不会滚
3. 不回滚特殊场景
使用 noRollbackFor 参数排除特定异常
@Transactional(noRollbackFor = {ValidationException.class})
public void validateData(Data data) {
// ValidationException不会触发回滚
}
编程式事务回滚:
1. 使用 TransactionTemplate 实现编程式事务
@Autowired
private TransactionTemplate transactionTemplate;
public void batchProcess() {
transactionTemplate.execute(status -> {
try {
// 业务操作...
if (errorCondition) status.setRollbackOnly();
return result;
} catch (Exception e) {
status.setRollbackOnly();
throw e;
}
});
}
2. 使用 PlatformTransactionManager 实现编程式事务
直接操作事务管理器实现完全控制
@Autowired
private PlatformTransactionManager transactionManager;
public void complexOperation() {
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
// 业务操作...
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw new ServiceException("操作失败", e);
}
}
嵌套事务与传播行为相关的异常回滚:
1. 嵌套事务(PROPAGATION_NESTED)
子事务作为父事务的保存点,可部分回滚
@Transactional(propagation = Propagation.REQUIRED)
public void parentMethod() {
// 主业务逻辑
childMethod(); // 嵌套子事务
}
@Transactional(propagation = Propagation.NESTED)
public void childMethod() {
// 子事务操作,失败仅回滚子操作
}
2.传播行为控制
通过传播策略控制事务边界:
REQUIRES_NEW:始终新建事务
MANDATORY:必须存在父事务
NOT_SUPPORTED:非事务执行
通过 xml 的方式配置全局回滚规则:
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="save*" rollback-for="java.lang.Exception"/>
<tx:method name="update*" no-rollback-for="BusinessWarning"/>
</tx:attributes>
</tx:advice>