From 61e8d452127c4c4c8d5ee527c229cc929a318468 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Fri, 6 Feb 2026 10:13:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=91=98=E5=B7=A5?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E5=BC=82=E6=AD=A5=E5=AE=9E=E7=8E=B0,?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=9C=9F=E6=AD=A3=E7=9A=84=E9=9D=9E=E9=98=BB?= =?UTF-8?q?=E5=A1=9E=E5=BC=82=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题分析: - Service方法同时使用@Async和CompletableFuture.supplyAsync - Controller调用future.get()会阻塞等待 - 这不是真正的异步 修复方案: - 移除@Async注解 - Service方法使用CompletableFuture.runAsync()异步执行doImport - Service方法改为void返回类型,立即返回 - Controller不调用future.get(),自己构建响应 - 实现真正的异步非阻塞导入 Co-Authored-By: Claude Sonnet 4.5 --- .../controller/CcdiEmployeeController.java | 11 ++++---- .../ccdi/service/ICcdiEmployeeService.java | 3 +-- .../service/impl/CcdiEmployeeServiceImpl.java | 26 +++---------------- 3 files changed, 11 insertions(+), 29 deletions(-) diff --git a/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/controller/CcdiEmployeeController.java b/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/controller/CcdiEmployeeController.java index 5a15f15..d2a3455 100644 --- a/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/controller/CcdiEmployeeController.java +++ b/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/controller/CcdiEmployeeController.java @@ -28,7 +28,6 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.List; -import java.util.concurrent.CompletableFuture; /** * 员工信息Controller @@ -137,11 +136,13 @@ public class CcdiEmployeeController extends BaseController { return error("至少需要一条数据"); } - // 异步导入,立即返回taskId - CompletableFuture future = employeeService.importEmployeeAsync(list, updateSupport); + // 提交异步任务 + employeeService.importEmployeeAsync(list, updateSupport); - // future已经完成,get()不会阻塞 - ImportResultVO result = future.get(); + // 立即返回,不等待后台任务完成 + ImportResultVO result = new ImportResultVO(); + result.setStatus("PROCESSING"); + result.setMessage("导入任务已提交,正在后台处理"); return AjaxResult.success("导入任务已提交,正在后台处理", result); } diff --git a/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/ICcdiEmployeeService.java b/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/ICcdiEmployeeService.java index 09cc3f5..baaca93 100644 --- a/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/ICcdiEmployeeService.java +++ b/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/ICcdiEmployeeService.java @@ -92,9 +92,8 @@ public interface ICcdiEmployeeService { * * @param excelList Excel数据列表 * @param isUpdateSupport 是否更新已存在的数据 - * @return 任务结果Future */ - CompletableFuture importEmployeeAsync(List excelList, Boolean isUpdateSupport); + void importEmployeeAsync(List excelList, Boolean isUpdateSupport); /** * 查询导入状态 diff --git a/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiEmployeeServiceImpl.java b/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiEmployeeServiceImpl.java index 092fed5..2c9536b 100644 --- a/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiEmployeeServiceImpl.java +++ b/ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiEmployeeServiceImpl.java @@ -20,7 +20,6 @@ import com.ruoyi.common.utils.StringUtils; import jakarta.annotation.Resource; import org.springframework.beans.BeanUtils; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -236,11 +235,9 @@ public class CcdiEmployeeServiceImpl implements ICcdiEmployeeService { * * @param excelList Excel数据列表 * @param isUpdateSupport 是否更新已存在的数据 - * @return 任务结果Future */ @Override - @Async("importExecutor") - public CompletableFuture importEmployeeAsync(List excelList, Boolean isUpdateSupport) { + public void importEmployeeAsync(List excelList, Boolean isUpdateSupport) { String taskId = UUID.randomUUID().toString(); long startTime = System.currentTimeMillis(); @@ -259,24 +256,16 @@ public class CcdiEmployeeServiceImpl implements ICcdiEmployeeService { redisTemplate.opsForHash().putAll(statusKey, statusData); redisTemplate.expire(statusKey, 7, TimeUnit.DAYS); - // 使用CompletableFuture.supplyAsync在独立的executor中异步执行doImport - return CompletableFuture.supplyAsync(() -> { + // 在独立线程中异步执行导入,立即返回 + CompletableFuture.runAsync(() -> { try { - // 在独立线程中执行导入 + // 在后台线程中执行导入 ImportResult result = doImport(excelList, isUpdateSupport, taskId); // 更新最终状态 String finalStatus = result.getFailureCount() == 0 ? "SUCCESS" : "PARTIAL_SUCCESS"; updateImportStatus(taskId, finalStatus, result, startTime); - // 构建返回结果 - ImportResultVO resultVO = new ImportResultVO(); - resultVO.setTaskId(taskId); - resultVO.setStatus(finalStatus); - resultVO.setMessage("导入完成"); - - return resultVO; - } catch (Exception e) { // 处理异常 Map errorData = new HashMap<>(); @@ -284,13 +273,6 @@ public class CcdiEmployeeServiceImpl implements ICcdiEmployeeService { errorData.put("message", "导入失败: " + e.getMessage()); errorData.put("endTime", System.currentTimeMillis()); redisTemplate.opsForHash().putAll(statusKey, errorData); - - ImportResultVO resultVO = new ImportResultVO(); - resultVO.setTaskId(taskId); - resultVO.setStatus("FAILED"); - resultVO.setMessage("导入失败: " + e.getMessage()); - - return resultVO; } }, importExecutor); }