本文主要解决:Spring @Async 注解多线程导致Spring的注解@Transactional失效问题!
问题:多线程为什么会导致事务注解@Transactional失效
实现AOP的方法有动态代理、编译期,类加载期织入等等,Spring实现AOP的方法则就是利用了动态代理机制,正因如此,才会导致某些情况下@Async和@Transactional不生效。
spring多线程的使用:
@Async注解使用如下
@EnableAsync //添加此注解开启异步调用(可用在配置类上,也可在启动类上标注)
public class ProviderApplication{
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
线程池配置采用自定义线程池配置类即可例如:
@Configuration
@EnableAsync
public class TaskPoolConfig {
@Autowired
private ThreadPoolProperties threadPoolProperties;
public final static String TASK_EXECUTOR="taskExecutor";
@Bean(TASK_EXECUTOR)
public Executor taskExecutor(){
//使用VisiableThreadPoolTaskExecutor 监控线程池清空
ThreadPoolTaskExecutor taskExecutor=new VisiableThreadPoolTaskExecutor();
//配置核心线程数
taskExecutor.setCorePoolSize(threadPoolProperties.getCorePoolSize());
//配置最大线程数
taskExecutor.setMaxPoolSize(threadPoolProperties.getMaxPoolSize());
//配置队列大小
taskExecutor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
//配置线程池中的线程的名称前缀
taskExecutor.setThreadNamePrefix(threadPoolProperties.getThreadNamePrefix());
//配置非核心线程超时时间
taskExecutor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 执行初始化
taskExecutor.initialize();
return taskExecutor;
}
}
yml配置如下:
executor:
corePoolSize: 20
maxPoolSize: 100
queueCapacity: 20
keepAliveSeconds: 60
threadNamePrefix: XCExecutor-
配置类中采用的 ThreadPoolProperties 类,是读取spring的yml配置文件获取:
@ConfigurationProperties(value = "executor")
@Component
public class ThreadPoolProperties {
/**
* 核心线程数量
*/
private Integer corePoolSize;
/**
* 当核心线程都在跑任务,还有多余的任务会存到此处
*/
private Integer maxPoolSize;
/**
* 如果queueCapacity存满了,还有任务就会启动更多的线程,直到线程数达到maxPoolSize。如果还有任务,则根据拒绝策略进行处理
*/
private Integer queueCapacity;
/**
* 非核心线程的超时时长,超长后会被回收
*/
private Integer keepAliveSeconds;
/**