spring 事务Propagation.REQUIRES_NEW 不起作用的原因

本文探讨了在Spring框架中使用@Transactional注解时,Propagation.REQUIRES_NEW不起作用的情况及原因。具体分析了目标对象自我调用时,由于未经过AOP代理而未能触发事务切面,导致该传播级别无法生效的现象,并提供了两种解决方案。

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

spring 事务Propagation.REQUIRES_NEW 不起作用的原因

接着上一篇遗留的问题

    @Transactional
    public String updateAccountTest(AccountTest accountTest) throws BusinessException {
        String strResult = "true";
        try {
            AccountMessage accountMessage = new AccountMessage();
            accountMessage.setMessage("修改用户" + accountTest.getName() + "金额" + accountTest.getMoney());
            this.updateAccountRequiresNew(accountTest); 
            // 如果updateAccountRequiresNew这个方法在本类定义,this.updateAccountRequiresNew(accountTest),结果又会是怎么样呢
            accountMessageBusinessImpl.insertAccountMessageRequired(accountMessage);
        } catch (BusinessException e) {
            logger.error("类:AccountTestServiceImpl;方法:updateAccountTest;错误信息:" + e);
            strResult = "false";
            throw e;
        } catch (RuntimeException e) {
            throw e;
        }
        return strResult;
    } 

    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public String updateAccountRequiresNew(AccountTest accountTest) throws BusinessException {
        String strResult = "true";
        try {
            accountTestServiceImpl.updateObject("updateAccountTest", accountTest);
        } catch (BusinessException e) {
            logger.error("类:AccountTestServiceImpl;方法:updateAccountTest;错误信息:" + e);
            strResult = "false";
            throw e;
        }
        return strResult;
    }
    @Transactional(propagation=Propagation.REQUIRED)
    public String insertAccountMessageRequired(AccountMessage accountMessage) throws BusinessException {
        String strResult = "true";
        try {
            accountMessageServiceImpl.saveObject("insertAccountMessage", accountMessage);
            int i=1/0;
        } catch (BusinessException e) {
            logger.error("类:AccountMessageServiceImpl;方法:insertAccountMessage;错误信息:" + e);
            strResult = "false";
            throw e;
        }
        return strResult;
    }
@Transactional(propagation=Propagation.REQUIRED)
    public String insertAccountMessageRequired(AccountMessage accountMessage) throws BusinessException {
        String strResult = "true";
        try {
            accountMessageServiceImpl.saveObject("insertAccountMessage", accountMessage);
            int i=1/0;
        } catch (BusinessException e) {
            logger.error("类:AccountMessageServiceImpl;方法:insertAccountMessage;错误信息:" + e);
            strResult = "false";
            throw e;
        }
        return strResult;
    }

执行完测试代码后
发现数据库余额表并没有变更
这里写图片描述

目标对象的自我调用 Propagation.REQUIRES_NEW 不会起作用的 。

why?

这里写图片描述
我们首先调用的是AOP代理对象而不是目标对象,首先执行事务切面,事务切面内部通过TransactionInterceptor环绕增强进行事务的增强,即进入目标方法之前开启事务,退出目标方法时提交/回滚事务。

目标对象内部的自我调用将无法实施切面中的增强。
这里写图片描述

此处的this指向目标对象,因此调用this.b()将不会执行b事务切面,即不会执行事务增强,因此b方法的事务定义“@Transactional(propagation = Propagation.REQUIRES_NEW)”将不会实施

解决方法
1:不要做内部调用
2:从beanFactory中获取bean SpringContextUtil.getBean(…)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值