@Transactional注解自调用失效问题详解

本文探讨了在Spring框架中使用@Transactional注解时可能遇到的失效问题,特别是自调用场景下如何避免事务管理失败。通过示例代码解释了AOP原理及解决策略。

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

问题描述

有时候我们在接口方法中配置了@Transactional的注解,但实际使用时却遇到@Transactional注解失效的问题,我们在这里选取一个比较隐秘的细节问题来剖析失效问题。

问题原因分析

注解@Transactional的底层实现是Spring AOP技术,而Spring AOP技术使用的是动态代理,这就意味着对于静态(static)方法和非public方法,注解@Transactional是失效的。还有一个更为隐秘的,而且在使用过程中极其容易犯错的——自调用
所谓自调用就是一个类的一个方法去调用自身另一个方法的过程。
示例代码:

@Service
public class RoleServiceImpl extends RoleService{
	
	@Autowired
	private RoleMapper roleMapper=null;
	
	@Override
	@Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED)
	public int insertRole(Role role) {
		
		return roleMapper.insertRole(role);
	}
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED)
	public int insertRoleList(List<Role> roleList) {
		int count=0;
		for (Role role:roleList) {
				insertRole(role);
				count++;
		}
		return count;
	}
	
}

在insertRoleList的方法实现中,它调用了自身类的实现insertRole方法,而insertRole方法声明是REQUIRES_NEW的传播行为,也就是每次调用该方法就会产生新的事务运行,但是实际结果却是每次插入都是用了相同的事务。也就是说在insertRole上标注的@Transcational失效了。
出现这个问题的根本原因在于AOP的实现原理。由于@Transcational的实现原理是AOP,而AOP的实现原理是动态代理,而在上述代码中使用的是自己调用自己的过程,也就是说根本不存在代理对象的调用,这样就不会产生AOP为我们设置@Transactional配置的参数,这样就出现了自调用注解失效的问题。

解决方法

为了解决这个问题可以使用两个服务类进行插入的调用,这样可以使SpringIoc容器生成代理对象,解决自调用的问题。
另一种方法是可以直接从容器中获取RoleService的代理对象,解决自调用问题。
示例代码:

@Override
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED)
public int insertRoleList(List<Role> roleList) {
	int count=0;
	//从容器中获取RoleService对象,实际是一个代理对象
	RoleService service = ctx.getBean(RoleService.class);
	for (Role role:roleList) {
			service.insertRole(role);
			count++;
	}
	return count;
}

从容器中获取代理对象的方法客服了自调用的过程,但是有一个弊端,就是从容器中获取对象的方法有侵入之嫌,你的类需要依赖于SpringIOC容器。所以我们推荐使用另一个服务类调用解决自调用问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值