Spring事务传播属性
Spring 事务传播属性,描述了Spring 的各个事务方法在相互调用时,事务是如何进行传播的。
Spring 事务有七个传播属性
Spring 事务控制原理
Spring 的事务控制是通过 Spring AOP 实现的,事务的 commit 或 rollback 操作都在 Spring 创建的代理类中实现。
举例说明,ServiceA.method1() 方法配置了 Spring 事务,实际 Spring 通过 AOP 生成了类 $ProxyA ,通过调用 $ProxyA 中增强的 method1() 方法(加入事务控制)来实现业务功能 & 事务控制。
Spring 事务传播的误区
有的同学可能会遇到一个问题,method1() 中调用 method2(),明明调用的 method2() 已经配置事务传播属性为 required_new,可是 Spring 并未给 method2() 开启新的事务。
查看代码发现,原来 method1() 和 method2() 在同一个类 ServiceA 中。
通过 Spring 事务控制原理可知,Spring 会生成代理类 $ServiceA,并通过调用 $ServiceA.method1() 来实现业务功能及事务控制;此时在 $ServiceA.method1() 中调用 method2(),实际上是不会生成新的代理类来增强 method2() 的,所以这时候 Spring 不会给 method2() 开启新的事务。
因此可知,同一个类中的方法相互调用,事务传播行为由最外层的方法的事务传播属性决定。
要解决这个问题,我目前知道有如下3种方法:
-
新建类 ServiceB,将 method2() 迁移到新的类中;
-
在 ServiceA.method1() 中,重新通过 Spring IOC 获取 ServiceA
ServiceA serviceA2 = applicationContext.getBean("serviceA");
再通过新获取的 serviceA2 来调用 method2()。此方法不推荐。
-
通过Spring配置暴露代理
-
<aop:aspectj-autoproxy expose-proxy="true"/>
或
-
<aop:config expose-proxy="true"/>
总而言之,尽量通过合理的建模或设计来利用Spring AOP带来的方便,并避免随之带来的问题。
-