注解@Transactional(rollbackFor = Exception.class) 的用法

本文探讨了在Spring框架下如何正确使用事务管理,特别是在循环中处理多个数据库操作时,如何确保部分失败不会影响整体事务的正确性。通过将业务逻辑放入独立的服务类并正确应用@Transactional注解,实现了细粒度的事务控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于业务需求要求,在一个Service的一个方法A中有一个for循环,每次循环里面的业务逻辑有可能发生异常,这个时候就需要将这个循环内的所有数据库操作给回滚掉,但是又不能影响到之前循环里数据的更改,并且后面的循环里不发生异常的情况下也需要正常操作数据库

for (int i = 0; i < educationInfoArrayList.size(); i++) {
    String result = insertOrUpdateByOnce(educationInfoArrayList.get(i), beforeEntryArrayList.get(i), afterEntryArrayList.get(i), educationExperienceArrayList.get(i),
            assessInfoArrayList.get(i), qualificationClassificationArrayList.get(i), trainingInfoArrayList.get(i));
}

@Transactional(rollbackFor = Exception.class)
public String insertOrUpdateByOnce(EducationInfo educationInfo, BeforeEntry beforeEntry, AfterEntry afterEntry, EducationExperience educationExperience, AssessInfo assessInfo,
        QualificationClassification qualificationClassification, TrainingInfo trainingInfo) {

    try {
        //这里写核心业务方法
    } catch (Exception e) {
        log.error("插入或者修改异常");
        //失败则手动回滚
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        //返回异常信息
        return e.getCause().getMessage();
    }

    return "success";

}

catch中加上手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(),事务也没有生效,且报错

org.springframework.transaction.NoTransactionException: No transaction aspect-managed TransactionStatus in scope
    at org.springframework.transaction.interceptor.TransactionAspectSupport.currentTransactionStatus(TransactionAspectSupport.java:122)
    at com.dubboconsumer.dubboConsumer.service.imp.DemoService.B(DemoService.java:44)
    at com.dubboconsumer.dubboConsumer.service.imp.DemoService.A(DemoService.java:20)
    at com.dubboconsumer.dubboConsumer.service.imp.DemoService$$FastClassBySpringCGLIB$$c7449c96.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:669)
    ...

原因是:调用了同一个类的方法,给这个方法配上事务注解是不会生效的,这个类里面没有事务,不能进行手动回滚;Spring之所以可以对开启@Transactional的方法进行事务管理,是因为Spring为当前类生成了一个代理类,然后在执行相关方法时,会判断这个方法有没有@Transactional注解,如果有的话,则会开启一个事务;所以,要把执行事务的方法全部丢到一个service类,在这个service类上配上注解@Transactional(rollbackFor = Exception.class),则这个service类中所有的方法都是执行事务的管理

 

for (int i = 0; i < educationInfoArrayList.size(); i++) {
    String result = insertOrUpdateEmployeeService.insertOrUpdateByOnce(educationInfoArrayList.get(i), beforeEntryArrayList.get(i), afterEntryArrayList.get(i), educationExperienceArrayList.get(i),
                    assessInfoArrayList.get(i), qualificationClassificationArrayList.get(i), trainingInfoArrayList.get(i));
}

 

@Repository
@Transactional(rollbackFor = Exception.class)
public class InsertOrUpdateEmployeeService {

    private static final Logger log = LoggerFactory.getLogger(InsertOrUpdateEmployeeService.class);

    @Autowired
    private EmployeeDao employeeDao;

    public String insertOrUpdateByOnce(EducationInfo educationInfo, BeforeEntry beforeEntry, AfterEntry afterEntry, EducationExperience educationExperience, AssessInfo assessInfo,
                                       QualificationClassification qualificationClassification, TrainingInfo trainingInfo) {

        try {
            //这里写核心业务方法
        } catch (Exception e) {
            log.error("插入或者修改异常");
            //失败则手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //返回异常信息
            return e.getCause().getMessage();
        }

        return "success";

    }
}

这样就符合事务管理的要求了

转载于:https://www.cnblogs.com/liuqing576598117/p/10783821.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值