spring中使用xml作为配置文件时@Async和@Transactional不起作用的情形

一、首先介绍一下如何@Async注解,

1xml头文件必须配置标记红色部分

spring中使用xml作为配置文件时@Async和@Transactional不起作用的情形

2配置任务和线程池

  1. <!-- 任务及线程池 -->

  2. <task:annotation-driven executor="asyncExecutor" />

  3. <task:executor id="asyncExecutor" pool-size="100-10000" queue-capacity="10"/>

  4. <!-- 注解扫描 -->

  5. <context:component-scan base-package="com.baisq">

  6. <context:include-filter type="annotation"

  7. expression="org.springframework.stereotype.Controller" />

  8. </context:component-scan>


3配置spring依赖的jar(不介绍这个了)

4在你需要异步调用的方法上使用@Async注解

spring中使用xml作为配置文件时@Async和@Transactional不起作用的情形

5但是你可能遇到@Async不起作用的时候,我就遇到了,我的问题是容器启动加载了如下两个xml文件

spring中使用xml作为配置文件时@Async和@Transactional不起作用的情形

springmvc.xml文件仅仅配置扫描注解,applicationContext.xml配置了任务和线程池和扫描注解,先加载了applicationContext.xml,后加载了springMvc.xml。

applicationContext.xml为扫描到的类加上@Async的作用(任务和线程池的配置依赖于扫描到的类),然后springMvc加载后的bean覆盖了applicationContext的bean,覆盖掉了@Async的作用,因为springmvc没有配置任务和线程池,

导致@Async没有起到作用。

6如果你遇到上述问题,检查一下加载的xml文件是否存在覆盖的问题。

二:@Transactional

使用@Transactional时,有几点需要注意:

    1)、必须保证这个注解修饰的方法是public方法

    2)、想要异常回滚,必须是非检查异常,即不用try-catch包裹,除非手动指明回滚类型rollbackFor=Exception.class

    3)、调用事务的方法必须和事务方法不在同一个类中

具体原因是springboot使用@Transactional注解和@Async注解的时候是使用代理模式,jdk代理或者是cglib代理需要被实现或者继承,所以必须是public方法,并且在同一类中方法在类体中执行,没法截获方法调用