fix: 优化删除和批量保存线程问题

This commit is contained in:
tangwei 2026-05-11 18:40:44 +08:00
parent c087ae1cad
commit 6e3918958b
3 changed files with 138 additions and 11 deletions

View File

@ -13,6 +13,9 @@ import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
@ -77,6 +80,12 @@ public class FishDraftDataController {
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
private final ExecutorService attachmentDeleteExecutor = Executors.newFixedThreadPool(4, r -> {
Thread t = new Thread(r, "attachment-delete");
t.setDaemon(true);
return t;
});
@PostMapping("/page")
@Operation(summary = "分页查询过鱼数据(关联电站和设施)")
public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) {
@ -260,7 +269,7 @@ public class FishDraftDataController {
// log.error("异步删除附件失败, dataId: {}", fishDraftData.getId(), e);
// }
// }
// }, taskExecutor).exceptionally(ex -> {
// }, attachmentDeleteExecutor).exceptionally(ex -> {
// log.error("异步删除任务执行异常", ex);
// return null;
// });
@ -301,7 +310,7 @@ public class FishDraftDataController {
log.error("异步删除附件失败, dataId: {}", fishDraftData.getId(), e);
}
}
}, taskExecutor).exceptionally(ex -> {
}, attachmentDeleteExecutor).exceptionally(ex -> {
log.error("异步删除任务执行异常", ex);
return null;
});
@ -1266,4 +1275,17 @@ public class FishDraftDataController {
return errors;
}
@jakarta.annotation.PreDestroy
public void shutdown() {
attachmentDeleteExecutor.shutdown();
try {
if (!attachmentDeleteExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
attachmentDeleteExecutor.shutdownNow();
}
} catch (InterruptedException e) {
attachmentDeleteExecutor.shutdownNow();
Thread.currentThread().interrupt();
}
}
}

View File

@ -39,6 +39,9 @@ import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Service
@Slf4j
@ -77,6 +80,12 @@ public class FishImportServiceImpl implements IFishImportService {
@Resource
private SysUserDataScopeMapper userDataScopeMapper;
private final ExecutorService attachmentExecutor = Executors.newFixedThreadPool(4, r -> {
Thread t = new Thread(r, "attachment-upload");
t.setDaemon(true);
return t;
});
private static final Map<String, String> EXCEL_COLUMN_MAPPING = new LinkedHashMap<>();
private static final Map<Integer, String> EXCEL_COLUMN_INDEX_MAPPING = new LinkedHashMap<>();
@ -1507,7 +1516,7 @@ public class FishImportServiceImpl implements IFishImportService {
String vdpth = data.getVdpth();
String picpth = data.getPicpth();
if(StrUtil.isBlank(vdpth) && StrUtil.isBlank(picpth)){
if (StrUtil.isBlank(vdpth) && StrUtil.isBlank(picpth)) {
log.error("数据不完整, 忽略处理");
return;
}
@ -1530,27 +1539,28 @@ public class FishImportServiceImpl implements IFishImportService {
data.setPicpth(uploadedPicpth);
}
}
fishDraftDataService.updateById(data);
log.info("异步上传附件完成, dataId: {},{},{}", data.getId(), data.getPicpth(), data.getVdpth());
} catch (Exception e) {
log.error("异步上传附件失败, dataId: {}", data.getId(), e);
} finally {
SecurityContextHolder.clearContext();
}
});
}, attachmentExecutor);
futures.add(future);
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenRun(() -> {
try {
// del 方法会递归删除目录及其所有内容
fishDraftDataService.updateBatchById(dataList);
log.info("批量更新附件路径完成, 共{}条", dataList.size());
} catch (Exception e) {
log.error("批量更新附件路径失败", e);
}
try {
FileUtil.del(tempDir);
} catch (Exception e) {
log.error("删除临时目录失败{}", e.getMessage());
}
})
.exceptionally(ex -> {
log.error("等待异步任务完成时发生异常", ex);
@ -1734,4 +1744,17 @@ public class FishImportServiceImpl implements IFishImportService {
}
return null;
}
@jakarta.annotation.PreDestroy
public void shutdown() {
attachmentExecutor.shutdown();
try {
if (!attachmentExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
attachmentExecutor.shutdownNow();
}
} catch (InterruptedException e) {
attachmentExecutor.shutdownNow();
Thread.currentThread().interrupt();
}
}
}

View File

@ -13,12 +13,94 @@ spring:
url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
username: "${DB_MASTER_USERNAME:QGC_REFA}"
password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}"
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 30000
async-init: true
keep-alive-between-time-millis: 120000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 180000
max-evictable-idle-time-millis: 300000
phy-timeout-millis: 25200000
validation-query: SELECT 1 FROM DUAL
validation-query-timeout: 3
test-while-idle: true
test-on-borrow: false
test-on-return: false
keep-alive: true
remove-abandoned: true
remove-abandoned-timeout: 1800
log-abandoned: true
break-after-acquire-failure: true
time-between-connect-error-millis: 300000
pool-prepared-statements: true
max-open-prepared-statements: 100
max-pool-prepared-statement-per-connection-size: 100
connection-properties: oracle.net.CONNECT_TIMEOUT=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000
slave:
driverClassName: oracle.jdbc.OracleDriver
url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
username: "${DB_SLAVE_USERNAME:QGC_REFA}"
password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}"
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 30000
async-init: true
keep-alive-between-time-millis: 120000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 180000
max-evictable-idle-time-millis: 300000
phy-timeout-millis: 25200000
validation-query: SELECT 1 FROM DUAL
validation-query-timeout: 3
test-while-idle: true
test-on-borrow: false
test-on-return: false
keep-alive: true
remove-abandoned: true
remove-abandoned-timeout: 1800
log-abandoned: true
break-after-acquire-failure: true
time-between-connect-error-millis: 300000
pool-prepared-statements: true
max-open-prepared-statements: 100
max-pool-prepared-statement-per-connection-size: 100
connection-properties: oracle.net.CONNECT_TIMEOUT=10000;oracle.jdbc.ReadTimeout=60000;oracle.net.READ_TIMEOUT=60000
filter:
stat:
enabled: true
log-slow-sql: true
slow-sql-millis: 3000
merge-sql: true
slf4j:
enabled: true
wall:
enabled: true
log-violation: true
throw-exception: true
config:
select-where-alway-true-check: true
select-having-alway-true-check: true
delete-where-alway-true-check: true
update-where-alay-true-check: true
update-where-alway-true-check: true
update-where-none-check: true
multi-statement-allow: false
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: '*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*'
session-stat-enable: true
principal-session-name: admin
profile-enable: true
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: admin
login-password: admin
reset-enable: false
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8