Spring @Async 注解多线程导致Spring的注解@Transactional失效问题

本文探讨了Spring @Async多线程执行时导致@Transactional事务失效的问题。由于Spring AOP的动态代理机制,当@Async与@Transactional结合使用时,可能导致事务管理失效。解决方案包括手动提交事务、正确配置@EnableAsync和理解事务传播级别。同时,多数据源情况下需注意线程间数据源同步。
摘要由CSDN通过智能技术生成

本文主要解决: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;
    /**
 
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值