在 java 自定义异常中配置 @transactional 的 rollbackfor,需要显式指定该自定义异常的类对象。默认情况下,spring 的事务管理器仅在捕获到 runtimeexception 或 error 时才会回滚事务;如果自定义异常继承自 exception(即受检异常),必须通过 rollbackfor 属性将其加入回滚列表,否则事务将正常提交。

如何声明自定义异常并配置回滚
首先定义一个继承自 Exception 的自定义异常类,然后在 Service 层的方法上使用 @Transactional(rollbackFor = YourCustomException.class)。这样当方法抛出该异常时,Spring 会拦截它并触发事务回滚。如果不配置 rollbackFor,由于 Exception 不是运行时异常,事务默认不会回滚,导致数据不一致。

package com.example.exception;
public class OrderNotFoundException extends Exception {
public OrderNotFoundException(String message) {
super(message);
}
}package com.example.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.exception.OrderNotFoundException;
@Service
public class OrderService {
@Transactional(rollbackFor = OrderNotFoundException.class)
public void processOrder(Long orderId) throws OrderNotFoundException {
// 模拟业务逻辑
if (orderId == null) {
throw new OrderNotFoundException("Order not found");
}
// 执行数据库操作...
}
}预期结果:当调用 processOrder(null) 时,抛出 OrderNotFoundException,事务回滚,数据库中的任何更改都不会生效。
立即学习“Java免费学习笔记(深入)”;
如何处理多个异常类型的回滚配置
如果一个方法可能抛出多种不同的异常,且都需要回滚事务,可以在 rollbackFor 数组中列出所有异常类。例如,除了自定义的 OrderNotFoundException,还可能有 InsufficientFundsException。配置方式为 rollbackFor = {OrderNotFoundException.class, InsufficientFundsException.class}。此外,也可以使用 rollbackForClassName 指定异常类名字符串,但推荐使用类对象方式以获得编译期检查。

package com.example.exception;
public class InsufficientFundsException extends Exception {
public InsufficientFundsException(String message) {
super(message);
}
}package com.example.service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.exception.OrderNotFoundException;
import com.example.exception.InsufficientFundsException;
@Service
public class PaymentService {
@Transactional(rollbackFor = {OrderNotFoundException.class, InsufficientFundsException.class})
public void payOrder(Long orderId, double amount) throws OrderNotFoundException, InsufficientFundsException {
// 检查订单是否存在
if (orderId == null) {
throw new OrderNotFoundException("Order not found");
}
// 检查余额
if (amount > 100.0) { // 假设余额不足阈值
throw new InsufficientFundsException("Insufficient funds");
}
// 执行支付...
}
}预期结果:当调用 payOrder(null, 50.0) 时,抛出 OrderNotFoundException,事务回滚;当调用 payOrder(1L, 200.0) 时,抛出 InsufficientFundsException,事务同样回滚。
基于程序中某个输入、条件或结果的具体问题
在上述代码中,如果 processOrder 方法内部抛出了 RuntimeException(如 NullPointerException),即使没有配置 rollbackFor,事务也会自动回滚,因为 RuntimeException 是 Spring 默认的回滚异常类型。但如果我们只配置了 rollbackFor = OrderNotFoundException.class,而方法抛出了 IllegalArgumentException,事务依然会回滚,因为 IllegalArgumentException 也是 RuntimeException 的子类。因此,rollbackFor 主要用于处理非运行时异常(即 Exception 的直接子类)的回滚需求。


















