返回信息流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)?
这是一条镜像帖。来源:北邮人论坛 / java / #53449同步于 2016/10/9
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
请教个事务的问题
hero210700
2016/10/9镜像同步2 回复
订阅后,新回复会通过你的通知中心匿名送达。
2 条回复
【 在 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对象执行方法,新事务特性生效。