BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #53449同步于 2016/10/9
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

请教个事务的问题

hero210700
2016/10/9镜像同步2 回复
public class ServiceBeanA { //事务T1 @Transaction public void methodA() { ... methodB();//事务T2生效 decorateMethod();//事务T2没有效果 ... } } public class ServiceBeanB { //封装 public void decorateMethod() { ... methodB(); ... } //事务T2 @Transactional(propagation = Propagation.REQUIRES_NEW) public void methodB() { ... } } 代码如上所述,spring中的事务嵌套问题。为什么只有在直接调用methodB的时候事务T2才算是新事务? 调用封装方法,封装的方法再调用methodB的时候就没有新事务T2了? (已知的是,嵌套的事务方法不能在同一个bean内,原因也不甚清楚) 最后一个问题: 封装之后的怎么才能嵌套一个事务(如上面的decorateMethond)?
订阅后,新回复会通过你的通知中心匿名送达。
2 条回复
ml3615556机器人#1 · 2016/10/10
关键词 AOP嵌套 代理
hero210700机器人#2 · 2016/10/11
【 在 hero210700 的大作中提到: 】 : public class ServiceBeanA { : //事务T1 : @Transaction : ................... 发现原因和解决办法了,在这里记录一下,可能还有问题,请有缘人不吝指教。 原因是spring的事务是利用aop实现的,这里有@Transactional方法的service都会生成一个cglib(我这里都是类,没有接口,接口貌似是JDK代理)代理对象,注入的时候不像其他bean似的constructor.newInstance()生成,而是这个代理类。 这样,在调用bean的事务方法时,会触发cglib代理类去判断一系列的interceptor,包括事务Interceptor,需要注意的是只有从bean调用时才会触发代理的intercep方法,在bean内部方法调用的时候不会判断interceptor,这也就解释了同一个bean内的两个传播类型不同的方法互相调用时,只有调用方事务特性生效。 而上面说的封装方法不生效的原因是,在进入封装方法时,proxy对象发现并没有任何@Transactional注解,也就没有interceptor所以会合并到外层事务,在调用methodB方法时,属于bean内部方法调用,也不会触发intercept方法,从而不会使methodB的事务属性生效。 解决办法是,要么使用aspectj来取代动态代理方式的aop,要么就是在事务bean里面拿到自己这个bean的引用(即自己注入自己),然后在调用方法的时候,方法前加上这个bean的引用,这样就会当做从proxy对象执行方法,新事务特性生效。