线程池子线程异常事务回滚

问题记录:使用多线程来处理任务子线程出现异常不回滚
解决思路:在子线程任务中手动提交回滚事务

顺便记录一下线程池的重要执行节点:

  1. 当任务来了之后,判断线程池中实际线程数是否小于核心线程数,如果小于就直接创建并执行任务。
  2. 当实际线程数大于核心线程数,他就会判断任务队列是否已满,如果未满就将任务存放队列即可。
  3. 判断线程池的实际线程数是否大于最大线程数,如果小于最大线程数,直接创建线程执行任务;实际线程数已经等于最大线程数,则会直接执行拒绝策略。
/**
     *
     * @param corePoolSize      核心线程数
     * @param maximumPoolSize   最大线程数
     * @param keepAliveTime     多余线程空余等待时间
     * @param unit              单位
     * @param workQueue         任务队列(需要手动指定最大任务数量,默认为Integer.MAX_VALUE,可能会内存溢出)
     * @param handler           任务拒绝策略
     *                          CallerRunsPolicy使用调用者的线程来执行任务
     *                          AbortPolicy拒绝执行,提示异常(默认)
     *                          DiscardPolicy拒绝该任务
     *                          DiscardOldestPolicy忽略最旧的任务
     */
    private static final ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 5, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(50), new ThreadPoolExecutor.CallerRunsPolicy());
    
    @Override
    @Transactional
    public ApiResult testThread() throws ExecutionException, InterruptedException {
        
        ApproveLog approveLog = new ApproveLog();
        approveLog.setAuditorRemark("主线程插入数据测试!");
        approveLogMapper.insert(approveLog);
        
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
             /*
             手动开启事务
             */
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            // 事物隔离级别,开启新事务,这样会比较安全些。
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 获得事务状态
            TransactionStatus status = dataSourceTransactionManager.getTransaction(def);
            
            try {
                approveLog.setAuditorRemark("子线程插入数据测试!");
                approveLogMapper.insert(approveLog);
                // 异常
                int a = 10 / 0;
                dataSourceTransactionManager.commit(status);
            } catch (Exception e) {
                log.error("有异常了!!!!!!!!");
                // 事务回滚
                dataSourceTransactionManager.rollback(status);
                throw new RuntimeException(e);
            }
            return "成功";
        }, poolExecutor).exceptionally(e -> {
            log.error("返回异常了!!!!!,{}", e);
            return "500";
        });
        // 如果返回500则是出现异常,手动抛异常回滚主线程
        if (future.get().equals("500")) {
            throw new RuntimeException("500");
        }
        return ApiResult.ok();
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值