每次批量新增1000行,遇到异常删除表数据
This commit is contained in:
parent
6065e0e65b
commit
aac756e5fa
@ -38,6 +38,7 @@ import com.yfd.platform.system.domain.LoginUser;
|
||||
import com.yfd.platform.utils.StringUtils;
|
||||
import com.yfd.platform.utils.TableNameContextHolder;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import lombok.val;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -46,6 +47,7 @@ import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@ -70,6 +72,8 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ChannelInboundHandlerAdapter.class);
|
||||
|
||||
private static final int BATCH_SIZE = 1000;
|
||||
|
||||
//试验任务节点表 Mapper
|
||||
@Resource
|
||||
private TsNodesMapper tsNodesMapper;
|
||||
@ -109,53 +113,178 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> getTsNodesTree(String nodeName, String taskId) {
|
||||
TsTask tsTask = tsTaskMapper.selectOne(new QueryWrapper<TsTask>().eq("id", taskId));
|
||||
// 查询所有节点数据
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
|
||||
// 查询所有节点数据(如果taskId为空,查询所有任务节点)
|
||||
List<Map<String, Object>> allNodes = getAllNodes(taskId);
|
||||
|
||||
// 查找所有根节点(parentId为"00"的节点)
|
||||
List<Map<String, Object>> rootNodes = findRootNodes(allNodes, taskId);
|
||||
|
||||
// 根节点的基本路径:/项目名称/
|
||||
String basePath = "/" + tsTask.getTaskName() + "/";
|
||||
|
||||
// 存储最终结果
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
Map<String, Object> rootNodeData = new HashMap<>();
|
||||
rootNodeData.put("nodeName", "根节点");
|
||||
rootNodeData.put("path", "/"+tsTask.getTaskName()+"/");
|
||||
rootNodeData.put("nodeId", tsTask.getId());
|
||||
rootNodeData.put("nodeOrder", "0");
|
||||
rootNodeData.put("taskId", tsTask.getId());
|
||||
rootNodeData.put("parentId", "00");
|
||||
result.add(rootNodeData);
|
||||
|
||||
// 如果 nodeName 为空,返回所有根节点的完整树形结构
|
||||
if (StringUtils.isEmpty(nodeName)) {
|
||||
if (!rootNodes.isEmpty()) {
|
||||
for (Map<String, Object> rootNode : rootNodes) {
|
||||
rootNode.put("path", basePath);
|
||||
result.addAll(buildFullTree(rootNode, allNodes));
|
||||
// 如果taskId为空,根据nodeName直接过滤
|
||||
if (StringUtils.isEmpty(taskId)) {
|
||||
if (StringUtils.isEmpty(nodeName)) {
|
||||
// 返回所有节点(需要按任务分组构建树)
|
||||
// return buildAllTaskTrees(allNodes);
|
||||
return result;
|
||||
} else {
|
||||
// 根据nodeName查询所有匹配节点,构建到根节点的路径
|
||||
return findNodesByName(allNodes, nodeName);
|
||||
}
|
||||
} else {
|
||||
// 原有逻辑:taskId不为空时按任务查询
|
||||
TsTask tsTask = tsTaskMapper.selectOne(new QueryWrapper<TsTask>().eq("id", taskId));
|
||||
if (tsTask == null) {
|
||||
throw new RuntimeException("任务不存在");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 否则,返回从根节点到目标节点的树形结构
|
||||
if (!rootNodes.isEmpty()) {
|
||||
for (Map<String, Object> rootNode : rootNodes) {
|
||||
rootNode.put("path", basePath);
|
||||
List<Map<String, Object>> tree = buildTreeToTargetNode(rootNode, allNodes, nodeName);
|
||||
if (!tree.isEmpty()) {
|
||||
List<Map<String, Object>> rootNodes = findRootNodes(allNodes, taskId);
|
||||
String basePath = "/" + tsTask.getTaskName() + "/";
|
||||
|
||||
Map<String, Object> rootNodeData = new HashMap<>();
|
||||
rootNodeData.put("nodeName", "根节点");
|
||||
rootNodeData.put("path", basePath);
|
||||
rootNodeData.put("nodeId", tsTask.getId());
|
||||
rootNodeData.put("nodeOrder", "0");
|
||||
rootNodeData.put("taskId", tsTask.getId());
|
||||
rootNodeData.put("taskName", tsTask.getTaskName());
|
||||
rootNodeData.put("parentId", "00");
|
||||
result.add(rootNodeData);
|
||||
|
||||
if (StringUtils.isEmpty(nodeName)) {
|
||||
for (Map<String, Object> rootNode : rootNodes) {
|
||||
rootNode.put("path", basePath);
|
||||
result.addAll(buildFullTree(rootNode, allNodes));
|
||||
}
|
||||
} else {
|
||||
for (Map<String, Object> rootNode : rootNodes) {
|
||||
rootNode.put("path", basePath);
|
||||
List<Map<String, Object>> tree = buildTreeToTargetNode(rootNode, allNodes, nodeName);
|
||||
result.addAll(tree);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 根据节点名称查找所有匹配节点并构建树
|
||||
*/
|
||||
private List<Map<String, Object>> findNodesByName(List<Map<String, Object>> allNodes, String nodeName) {
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
|
||||
// 查找所有匹配的节点
|
||||
List<Map<String, Object>> matchedNodes = allNodes.stream()
|
||||
.filter(node -> {
|
||||
Object nodeNameObj = node.get("nodeName");
|
||||
if (nodeNameObj instanceof String) {
|
||||
String currentName = (String) nodeNameObj;
|
||||
return currentName.toLowerCase().contains(nodeName.toLowerCase());
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 为每个匹配节点构建到根节点的路径
|
||||
for (Map<String, Object> matchedNode : matchedNodes) {
|
||||
// 找到该节点的完整路径
|
||||
List<Map<String, Object>> pathToRoot = findPathToRoot(matchedNode, allNodes);
|
||||
if (!pathToRoot.isEmpty()) {
|
||||
result.addAll(pathToRoot);
|
||||
}
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找节点到根节点的路径
|
||||
*/
|
||||
private List<Map<String, Object>> findPathToRoot(Map<String, Object> node, List<Map<String, Object>> allNodes) {
|
||||
List<Map<String, Object>> path = new ArrayList<>();
|
||||
Map<String, Object> currentNode = node;
|
||||
|
||||
// 向上查找直到根节点
|
||||
while (currentNode != null) {
|
||||
path.add(0, new HashMap<>(currentNode)); // 添加到路径开头
|
||||
|
||||
String parentId = (String) currentNode.get("parentId");
|
||||
if ("00".equals(parentId)) {
|
||||
// 找到根节点,添加任务信息
|
||||
String taskId = (String) currentNode.get("taskId");
|
||||
TsTask task = tsTaskMapper.selectOne(new QueryWrapper<TsTask>().eq("id", taskId));
|
||||
if (task != null) {
|
||||
Map<String, Object> taskNode = new HashMap<>();
|
||||
taskNode.put("nodeName", "根节点");
|
||||
taskNode.put("path", "/" + task.getTaskName() + "/");
|
||||
taskNode.put("nodeId", task.getId());
|
||||
taskNode.put("nodeOrder", "0");
|
||||
taskNode.put("taskId", task.getId());
|
||||
taskNode.put("taskName", task.getTaskName());
|
||||
taskNode.put("parentId", "00");
|
||||
path.add(0, taskNode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 查找父节点
|
||||
String finalParentId = parentId;
|
||||
currentNode = allNodes.stream()
|
||||
.filter(n -> finalParentId.equals(n.get("nodeId")))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
// public List<Map<String, Object>> getTsNodesTree(String nodeName, String taskId) {
|
||||
// TsTask tsTask = tsTaskMapper.selectOne(new QueryWrapper<TsTask>().eq("id", taskId));
|
||||
// // 查询所有节点数据
|
||||
// List<Map<String, Object>> allNodes = getAllNodes(taskId);
|
||||
//
|
||||
// // 查找所有根节点(parentId为"00"的节点)
|
||||
// List<Map<String, Object>> rootNodes = findRootNodes(allNodes, taskId);
|
||||
//
|
||||
// // 根节点的基本路径:/项目名称/
|
||||
// String basePath = "/" + tsTask.getTaskName() + "/";
|
||||
//
|
||||
// // 存储最终结果
|
||||
// List<Map<String, Object>> result = new ArrayList<>();
|
||||
// Map<String, Object> rootNodeData = new HashMap<>();
|
||||
// rootNodeData.put("nodeName", "根节点");
|
||||
// rootNodeData.put("path", "/"+tsTask.getTaskName()+"/");
|
||||
// rootNodeData.put("nodeId", tsTask.getId());
|
||||
// rootNodeData.put("nodeOrder", "0");
|
||||
// rootNodeData.put("taskId", tsTask.getId());
|
||||
// rootNodeData.put("parentId", "00");
|
||||
// result.add(rootNodeData);
|
||||
//
|
||||
// // 如果 nodeName 为空,返回所有根节点的完整树形结构
|
||||
// if (StringUtils.isEmpty(nodeName)) {
|
||||
// if (!rootNodes.isEmpty()) {
|
||||
// for (Map<String, Object> rootNode : rootNodes) {
|
||||
// rootNode.put("path", basePath);
|
||||
// result.addAll(buildFullTree(rootNode, allNodes));
|
||||
// }
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// // 否则,返回从根节点到目标节点的树形结构
|
||||
// if (!rootNodes.isEmpty()) {
|
||||
// for (Map<String, Object> rootNode : rootNodes) {
|
||||
// rootNode.put("path", basePath);
|
||||
// List<Map<String, Object>> tree = buildTreeToTargetNode(rootNode, allNodes, nodeName);
|
||||
// if (!tree.isEmpty()) {
|
||||
// result.addAll(tree);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 返回结果
|
||||
// return result;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 查询所有节点数据
|
||||
*
|
||||
@ -726,6 +855,7 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
taskStatusHolder.finishTask(asyncKey);
|
||||
WebSocketServer.sendMessageTo("试验数据扫描接口完成", "taskId_" + id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**********************************
|
||||
@ -789,6 +919,15 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
return "扫描完成";
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("执行试验数据扫描时发生未知异常: {}", e.getMessage(), e);
|
||||
//异常的时候删除节点和文件表
|
||||
LambdaQueryWrapper<TsNodes> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(TsNodes::getTaskId, id);
|
||||
tsNodesMapper.delete(queryWrapper);
|
||||
|
||||
LambdaQueryWrapper<TsFiles> queryWrapperTsFile = new LambdaQueryWrapper<>();
|
||||
queryWrapperTsFile.eq(TsFiles::getTaskId, id);
|
||||
tsFilesMapper.delete(queryWrapperTsFile);
|
||||
|
||||
return "扫描失败:" + e.getMessage();
|
||||
} finally {
|
||||
TableNameContextHolder.clear();
|
||||
@ -978,12 +1117,18 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
// 批量插入文件表(忽略重复)
|
||||
if (!tsFilesToCreate.isEmpty()) {
|
||||
long startBatchInsertFiles = System.currentTimeMillis();
|
||||
int affectedRowsFiles = tsFilesMapper.batchInsertTsFiles(tsFilesToCreate);
|
||||
//int affectedRowsFiles = tsFilesMapper.batchInsertTsFiles(tsFilesToCreate);
|
||||
int affected = 0;
|
||||
for (int i = 0; i < tsFilesToCreate.size(); i += BATCH_SIZE) {
|
||||
List<TsFiles> sub =
|
||||
new ArrayList<>(tsFilesToCreate.subList(i, Math.min(i + BATCH_SIZE, tsFilesToCreate.size())));
|
||||
affected += this.insertOneBatch(sub);
|
||||
}
|
||||
|
||||
LOGGER.info("[批量插入试验任务文件表] 耗时 {} ms | 实际新增数量: {} 条",
|
||||
System.currentTimeMillis() - startBatchInsertFiles,
|
||||
affectedRowsFiles);
|
||||
affected);
|
||||
}
|
||||
|
||||
// 记录开始时间
|
||||
long startTimeFiles = System.currentTimeMillis();
|
||||
// 执行更新操作 taskId, String nodeId
|
||||
@ -996,6 +1141,14 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
||||
LOGGER.info("文件表中的节点ID更新完成,影响 {} 行,总耗时 {} 毫秒", affectedLevelFilesRows, costTimeFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* 每批独立事务插入
|
||||
*/
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
|
||||
public int insertOneBatch(List<TsFiles> batch) {
|
||||
return tsFilesMapper.batchInsertTsFiles(batch);
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保路径格式为以 "/" 开头和结尾(例如 "/data/test/")
|
||||
* 若路径为空或非法,返回根路径 "/"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user