spring管理事务,如何避免事务失效?

本文主要介绍使用spring管理事务时因为开发编码导致事务失效的场景,主要讲述开发最容易忽略的场景。

1.方法内部调用 + 事务传播行为配置不当场景

示例代码

@Slf4j
@Service
public class DemoServiceImpl implements DemoService {
   
   

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void service1() {
   
   
        boolean active = TransactionSynchronizationManager.isActualTransactionActive();
        log.info("service1 is exist transaction:{}", active);
        if (active) {
   
   
            String name = TransactionSynchronizationManager.getCurrentTransactionName();
            log.info("service1 transaction name:{}", name);
        }
        service2();
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void service2() {
   
   
        boolean active = TransactionSynchronizationManager.isActualTransactionActive();
        log.info("service2 is exist transaction:{}", active);
        if (active) {
   
   
            String name = TransactionSynchronizationManager.getCurrentTransactionName();
            log.info("service2 transaction name:{}", name);
        }
    }
}

测试代码

模拟Controller调用Service场景。

@SpringBootTest(classes = SpringBootTransactionApplication.class)
public class SpringBootTransactionTest {
   
   

    @Autowired
    private DemoService demoService;

    @Test
    void test() {
   
   
        demoService.service1();
    }
}

场景导入

上述示例代码中,service1方法内部调用了service2方法,由于service1方法和service2方法同属于一个service接口(类)中,并不能在service实现类中再注入自己本身,因此我们就随手写了一个service2(),亦或是this.service2(),于是问题就产生了!

问题分析

service1方法添加了 @Transactional 注解,并且指定了事务的传播行为是Propagation.REQUIRED(不做过多介绍),当测试代码调用service1方法时,spring会为DemoServiceImpl 生成一个代理对象,并且开启一个新事物(如果当前存在事务则加入)。当代码执行到service2方法时,由于默认使用this对象去调用,因此spring不会使用代理对象去调用service2方法,而是直接使用原生的对象去调用service2方法,相当于 new DemoServiceImpl().service2(),这样service2方法上添加的 @Transactional 注解就无效了,这就是方法内部调用导致的事物失效!

结果分析

虽然上述调用方式导致了service2方法上添加的 @Transactional 注解失效,但是不代表执行service2方法时就一定没有事务,业务上也不一定就错误。继续接着分析,当执行到serv

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值