每次批量新增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.StringUtils;
|
||||||
import com.yfd.platform.utils.TableNameContextHolder;
|
import com.yfd.platform.utils.TableNameContextHolder;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import lombok.val;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
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.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
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 Logger LOGGER = LoggerFactory.getLogger(ChannelInboundHandlerAdapter.class);
|
||||||
|
|
||||||
|
private static final int BATCH_SIZE = 1000;
|
||||||
|
|
||||||
//试验任务节点表 Mapper
|
//试验任务节点表 Mapper
|
||||||
@Resource
|
@Resource
|
||||||
private TsNodesMapper tsNodesMapper;
|
private TsNodesMapper tsNodesMapper;
|
||||||
@ -109,53 +113,178 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String, Object>> getTsNodesTree(String nodeName, String taskId) {
|
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);
|
List<Map<String, Object>> allNodes = getAllNodes(taskId);
|
||||||
|
|
||||||
// 查找所有根节点(parentId为"00"的节点)
|
// 如果taskId为空,根据nodeName直接过滤
|
||||||
List<Map<String, Object>> rootNodes = findRootNodes(allNodes, taskId);
|
if (StringUtils.isEmpty(taskId)) {
|
||||||
|
if (StringUtils.isEmpty(nodeName)) {
|
||||||
// 根节点的基本路径:/项目名称/
|
// 返回所有节点(需要按任务分组构建树)
|
||||||
String basePath = "/" + tsTask.getTaskName() + "/";
|
// return buildAllTaskTrees(allNodes);
|
||||||
|
return result;
|
||||||
// 存储最终结果
|
} else {
|
||||||
List<Map<String, Object>> result = new ArrayList<>();
|
// 根据nodeName查询所有匹配节点,构建到根节点的路径
|
||||||
Map<String, Object> rootNodeData = new HashMap<>();
|
return findNodesByName(allNodes, nodeName);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 原有逻辑:taskId不为空时按任务查询
|
||||||
|
TsTask tsTask = tsTaskMapper.selectOne(new QueryWrapper<TsTask>().eq("id", taskId));
|
||||||
|
if (tsTask == null) {
|
||||||
|
throw new RuntimeException("任务不存在");
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 否则,返回从根节点到目标节点的树形结构
|
List<Map<String, Object>> rootNodes = findRootNodes(allNodes, taskId);
|
||||||
if (!rootNodes.isEmpty()) {
|
String basePath = "/" + tsTask.getTaskName() + "/";
|
||||||
for (Map<String, Object> rootNode : rootNodes) {
|
|
||||||
rootNode.put("path", basePath);
|
Map<String, Object> rootNodeData = new HashMap<>();
|
||||||
List<Map<String, Object>> tree = buildTreeToTargetNode(rootNode, allNodes, nodeName);
|
rootNodeData.put("nodeName", "根节点");
|
||||||
if (!tree.isEmpty()) {
|
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);
|
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;
|
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);
|
taskStatusHolder.finishTask(asyncKey);
|
||||||
WebSocketServer.sendMessageTo("试验数据扫描接口完成", "taskId_" + id);
|
WebSocketServer.sendMessageTo("试验数据扫描接口完成", "taskId_" + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
@ -789,6 +919,15 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
|||||||
return "扫描完成";
|
return "扫描完成";
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.error("执行试验数据扫描时发生未知异常: {}", e.getMessage(), 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();
|
return "扫描失败:" + e.getMessage();
|
||||||
} finally {
|
} finally {
|
||||||
TableNameContextHolder.clear();
|
TableNameContextHolder.clear();
|
||||||
@ -978,12 +1117,18 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
|||||||
// 批量插入文件表(忽略重复)
|
// 批量插入文件表(忽略重复)
|
||||||
if (!tsFilesToCreate.isEmpty()) {
|
if (!tsFilesToCreate.isEmpty()) {
|
||||||
long startBatchInsertFiles = System.currentTimeMillis();
|
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 | 实际新增数量: {} 条",
|
LOGGER.info("[批量插入试验任务文件表] 耗时 {} ms | 实际新增数量: {} 条",
|
||||||
System.currentTimeMillis() - startBatchInsertFiles,
|
System.currentTimeMillis() - startBatchInsertFiles,
|
||||||
affectedRowsFiles);
|
affected);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录开始时间
|
// 记录开始时间
|
||||||
long startTimeFiles = System.currentTimeMillis();
|
long startTimeFiles = System.currentTimeMillis();
|
||||||
// 执行更新操作 taskId, String nodeId
|
// 执行更新操作 taskId, String nodeId
|
||||||
@ -996,6 +1141,14 @@ public class TsNodesServiceImpl extends ServiceImpl<TsNodesMapper, TsNodes> impl
|
|||||||
LOGGER.info("文件表中的节点ID更新完成,影响 {} 行,总耗时 {} 毫秒", affectedLevelFilesRows, costTimeFiles);
|
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/")
|
* 确保路径格式为以 "/" 开头和结尾(例如 "/data/test/")
|
||||||
* 若路径为空或非法,返回根路径 "/"
|
* 若路径为空或非法,返回根路径 "/"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user