spring @transactional public和自调用方法的问题处理
来源:互联网 发布:蜂云网络 51订货网 编辑:程序博客网 时间:2024/06/05 02:03
@Transactional 只能应用到 public 方法才有效
只有@Transactional 注解应用到 public 方法,才能进行事务管理。这是因为在使用 Spring AOP 代理时,Spring 在调用在图 1 中的 TransactionInterceptor 在目标方法执行前后进行拦截之前,DynamicAdvisedInterceptor(CglibAopProxy 的内部类)的的 intercept 方法或 JdkDynamicAopProxy 的 invoke 方法会间接调用 AbstractFallbackTransactionAttributeSource(Spring 通过这个类获取表 1. @Transactional 注解的事务属性配置属性信息)的 computeTransactionAttribute 方法。
清单 4. AbstractFallbackTransactionAttributeSource
protected TransactionAttribute computeTransactionAttribute(Method method,
Class<?> targetClass) {
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;}
这个方法会检查目标方法的修饰符是不是 public,若不是 public,就不会获取@Transactional 的属性配置信息,最终会造成不会用 TransactionInterceptor 来拦截该目标方法进行事务管理。
避免 Spring 的 AOP 的自调用问题
在 Spring 的 AOP 代理下,只有目标方法由外部调用,目标方法才由 Spring 生成的代理对象来管理,这会造成自调用问题。若同一类中的其他没有@Transactional 注解的方法内部调用有@Transactional 注解的方法,有@Transactional 注解的方法的事务被忽略,不会发生回滚。见清单 5 举例代码展示。
清单 5.自调用问题举例
@Service
-->public class OrderService {
private void insert() {
insertOrder();
}
@Transactional
public void insertOrder() {
//insert log info
//insertOrder
//updateAccount
}
}
insertOrder 尽管有@Transactional 注解,但它被内部方法 insert 调用,事务被忽略,出现异常事务不会发生回滚。
上面的两个问题@Transactional 注解只应用到 public 方法和自调用问题,是由于使用 Spring AOP 代理造成的。为解决这两个问题,使用 AspectJ 取代 Spring AOP 代理。
需要将下面的 AspectJ 信息添加到 xml 配置信息中。
清单 6. AspectJ 的 xml 配置信息
<
tx:annotation-driven
mode
=
"aspectj"
/>
<
bean
id
=
"transactionManager"
class
=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"
>
<
property
name
=
"dataSource"
ref
=
"dataSource"
/>
</
bean
>
</
bean
class
=
"org.springframework.transaction.aspectj.AnnotationTransactionAspect"
factory-method
=
"aspectOf"
>
<
property
name
=
"transactionManager"
ref
=
"transactionManager"
/>
</
bean
>
同时在 Maven 的 pom 文件中加入 spring-aspects 和 aspectjrt 的 dependency 以及 aspectj-maven-plugin。
清单 7. AspectJ 的 pom 配置信息
<
dependency
>
<
groupId
>org.springframework</
groupId
>
<
artifactId
>spring-aspects</
artifactId
>
<
version
>4.3.2.RELEASE</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.aspectj</
groupId
>
<
artifactId
>aspectjrt</
artifactId
>
<
version
>1.8.9</
version
>
</
dependency
>
<
plugin
>
<
groupId
>org.codehaus.mojo</
groupId
>
<
artifactId
>aspectj-maven-plugin</
artifactId
>
<
version
>1.9</
version
>
<
configuration
>
<
showWeaveInfo
>true</
showWeaveInfo
>
<
aspectLibraries
>
<
aspectLibrary
>
<
groupId
>org.springframework</
groupId
>
<
artifactId
>spring-aspects</
artifactId
>
</
aspectLibrary
>
</
aspectLibraries
>
</
configuration
>
<
executions
>
<
execution
>
<
goals
>
<
goal
>compile</
goal
>
<
goal
>test-compile</
goal
>
</
goals
>
</
execution
>
</
executions
>
</
plugin
>
透彻的掌握 Spring 中@transactional 的使用
- spring @transactional public和自调用方法的问题处理
- spring @transactional 和synchronized同时使用不能同步的问题
- 多线程调用spring的@Transactional保存数据
- Spring 没有注解的方法 调用@Transactional注解方法,不执行
- Spring中声明式事务的注解@Transactional的参数的总结(REQUIRED和REQUIRES_NEW的与主方法的回滚问题)
- Spring 从同一个类中的某个方法调用另一个有注解(@Transactional)的方法时,失效的解决方案
- spring boot @Transactional事物处理
- spring中@Transactional对于事务异常的处理
- spring中"Closing non transactional SqlSession"的处理
- spring的@Transactional()用
- spring的@Transactional
- Spring 的 @Transactional事务
- Spring的@Transactional
- spring的@Transactional详解
- private和public的问题
- Spring事务@Transactional小问题
- spring @Transactional 方法内事务不起作用的解决办法
- 高并发下Spring使用@Transactional 的问题
- spring-cloud-zuul服务网关(五)
- spring顶级框架
- 堆和优先权队列
- BeanUtils工具详解
- 做到这一点,你也可以成为优秀的程序员
- spring @transactional public和自调用方法的问题处理
- AVAudioPlayer 播放音频
- C程序中常见的与存储器有关的错误
- 一步一步制作yaffs/yaffs2根文件系统(七)---真挚地道歉以及纠正前边出现的错误!
- 关于使用memset(a,0xff,sizeof(a)),输出-1的问题
- HTTP错误码
- CentOS 单个Tomcat 的启动服务脚本
- rst是复位报文 几种TCP链接中出现rst的情况
- Postfix重要数据结构