@Transactional自调用失效问题

12 篇文章 0 订阅
9 篇文章 0 订阅

@Transactional自调用失效问题

@Transactional在某些场景下会失效,我们把传播行为修改为REQUIRESNEW,也就是每次调用产生新的事务

@Transactional(isolation = Isolaton.READCOMMITTED, propagation = Propagation.REQUIRED) 
public int insertUsers (List<User> userList) { 
	int count = 0; 
	for (User user : userList) 
	{ 
		//调用自己类自身的方法,产生自调用问题
		count += insertUser(user), 
	}
	return count; 
}
	//传播行为为REQUIRESNEW每次调用产生新事务
@Override 
@Transactional(isolation =Isolation.READ COMMITTED, propagation = PropagatonREQUIRESNEW) 
publicntinsertUser (User user) { 
	return userDao.insertUser(user); 
}

这是一个类自身方法之间的调用,我称之为自调用.
pring数据库事务约定其实原理是AOP,AOP的原理是在自调用的过程中是类自身的调用,而不是理对象去调用,那么就不会产生AOP,这样Spring就不能把你的代码织入到约定的流程中于是就产生了现在看到的失败场景。为了克服这个问题,需要用一个Service去调用另一Service这样就是将代理对象的调用,Spring会将你的代码织入事务流程。

或者改造代码:

@Au tow ired prvateUserDao userDao = null; 
private ApplicatonContextapplicationContext = null; 
//实现生命周期方法,设置IoC容器@Oerride
public void setApplicationContext(ApplicationContext  applicationContext)  throws BeansException {
	this.applicationContext = applicationContext; 
}

@Transactional(isolation = Isolaton.READCOMMITTED, propagation = Propagation.REQUIRED) 
public int insertUsers (List<User> userList) { 
	int count = 0;
	//从IOC容器中取代理对象
	UserService userService = applicationContext.getBean(UserService.class);  
	for (User user : userList) 
	{ 
		//调用自己类自身的方法,产生自调用问题
		count += userService .insertUser(user), 
	}
	return count; 
}
	//传播行为为REQUIRESNEW每次调用产生新事务
@Override 
@Transactional(isolation =Isolation.READ COMMITTED, propagation = PropagatonREQUIRESNEW) 
publicntinsertUser (User user) { 
	return userDao.insertUser(user); 
}

从代码中我实现了ApplicationContextAware 接口setApplicationContext方法这样便够把IoC容器设置到这个类中来。于是在setUser方法中,我通过Io容器取了UserService口对象。但是请注意这将是一个理对象并且使用传播行为为REUIRES_NEW的insertUse方法,这样才可以运行功。
这样自调用的问题就克服了,只是这样代码需要依赖于Spring的API,这样会造成代码的侵入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值