diff --git a/ruoyi-admin/src/main/java/com/neuhis/his/service/IOracleSysService.java b/ruoyi-admin/src/main/java/com/neuhis/his/service/IOracleSysService.java index b2e71d940..a9e9d74c4 100644 --- a/ruoyi-admin/src/main/java/com/neuhis/his/service/IOracleSysService.java +++ b/ruoyi-admin/src/main/java/com/neuhis/his/service/IOracleSysService.java @@ -3,7 +3,9 @@ package com.neuhis.his.service; import com.neuhis.his.domain.dto.DeadLock; import com.neuhis.his.domain.dto.DeadLockRac; +import java.util.HashMap; import java.util.List; +import java.util.Map; public interface IOracleSysService { @@ -23,4 +25,55 @@ public interface IOracleSysService { * 杀进程 */ void killSession(String sessionStr); + + //进程列表:本进程号SID、阻塞id 三列 + //1、“阻塞id”有四种情况,先找:“的SQL阻塞了本语句”的取得:“【SID=”的取值 + //2、找到:“本进程号SID” = “【SID=”的一行,如果本行:“阻塞id”是 情况3,结束,否则继续递归。 + class DeadlockResolver { + public static final String BLOCK_FIND_TXT = "的SQL阻塞了本语句"; + public static final String BLOCK_ROOT_TXT = "根锁为此会话杀我KILL ME or igore"; + public static DeadLockRac findProblematicSession(List deadlockList) { + Map sidMap = new HashMap<>(); + + // First pass: build a map for quick lookup by SID + for (DeadLockRac deadlock : deadlockList) { + sidMap.put(deadlock.get本进程号SID(), deadlock); + } + + // Second pass: look for entries that match the criteria + for (DeadLockRac deadlock : deadlockList) { + if (deadlock.get阻塞SID().contains(BLOCK_FIND_TXT)) { + // Extract the blocking SID + int blockingSID = extractBlockingSID(deadlock.get阻塞SID()); + DeadLockRac blockingSession = sidMap.get(blockingSID); + + // Check if the blocking session's 阻塞SID is of case 3 + while (blockingSession != null && !isRootBlock(blockingSession.get阻塞SID())) { + // If not case 3, recursively check the blocker of this session + String sqlText = blockingSession.get阻塞SID(); + if (sqlText.contains(BLOCK_FIND_TXT)) { + blockingSID = extractBlockingSID(sqlText); + blockingSession = sidMap.get(blockingSID); + } else { + break; // Exit loop if it doesn't match case 4 anymore + } + } + if (blockingSession != null && isRootBlock(blockingSession.get阻塞SID())) { + return blockingSession; // Found problematic session + } + } + } + return null; // No problematic session found + } + + private static boolean isRootBlock(String sqlText) { + return sqlText.contains(BLOCK_ROOT_TXT); + } + + private static int extractBlockingSID(String sqlText) { + // Assuming format is like "...【SID=4903】..." + String sidStr = sqlText.substring(sqlText.indexOf("【SID=") + 5, sqlText.indexOf("】")); + return Integer.parseInt(sidStr.trim()); + } + } } diff --git a/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/OracleSysServiceImpl.java b/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/OracleSysServiceImpl.java index cc578e8cb..53b06df6d 100644 --- a/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/OracleSysServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/OracleSysServiceImpl.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Map; @Slf4j -@Service +@Service(value = "oracleSysService_his") @DataSource(value = DataSourceType.SLAVE) public class OracleSysServiceImpl implements IOracleSysService { @Resource @@ -70,55 +70,4 @@ public class OracleSysServiceImpl implements IOracleSysService { } return Lists.newArrayList(); } - - //进程列表:本进程号SID、阻塞id 三列 - //1、“阻塞id”有四种情况,先找:“的SQL阻塞了本语句”的取得:“【SID=”的取值 - //2、找到:“本进程号SID” = “【SID=”的一行,如果本行:“阻塞id”是 情况3,结束,否则继续递归。 - private static class DeadlockResolver { - public static final String BLOCK_FIND_TXT = "的SQL阻塞了本语句"; - public static final String BLOCK_ROOT_TXT = "根锁为此会话杀我KILL ME or igore"; - public static DeadLockRac findProblematicSession(List deadlockList) { - Map sidMap = new HashMap<>(); - - // First pass: build a map for quick lookup by SID - for (DeadLockRac deadlock : deadlockList) { - sidMap.put(deadlock.get本进程号SID(), deadlock); - } - - // Second pass: look for entries that match the criteria - for (DeadLockRac deadlock : deadlockList) { - if (deadlock.get阻塞SID().contains(BLOCK_FIND_TXT)) { - // Extract the blocking SID - int blockingSID = extractBlockingSID(deadlock.get阻塞SID()); - DeadLockRac blockingSession = sidMap.get(blockingSID); - - // Check if the blocking session's 阻塞SID is of case 3 - while (blockingSession != null && !isRootBlock(blockingSession.get阻塞SID())) { - // If not case 3, recursively check the blocker of this session - String sqlText = blockingSession.get阻塞SID(); - if (sqlText.contains(BLOCK_FIND_TXT)) { - blockingSID = extractBlockingSID(sqlText); - blockingSession = sidMap.get(blockingSID); - } else { - break; // Exit loop if it doesn't match case 4 anymore - } - } - if (blockingSession != null && isRootBlock(blockingSession.get阻塞SID())) { - return blockingSession; // Found problematic session - } - } - } - return null; // No problematic session found - } - - private static boolean isRootBlock(String sqlText) { - return sqlText.contains(BLOCK_ROOT_TXT); - } - - private static int extractBlockingSID(String sqlText) { - // Assuming format is like "...【SID=4903】..." - String sidStr = sqlText.substring(sqlText.indexOf("【SID=") + 5, sqlText.indexOf("】")); - return Integer.parseInt(sidStr.trim()); - } - } } diff --git a/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/OracleSysServicePacsImpl.java b/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/OracleSysServicePacsImpl.java new file mode 100644 index 000000000..fee95d7ec --- /dev/null +++ b/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/OracleSysServicePacsImpl.java @@ -0,0 +1,69 @@ +package com.neuhis.his.service.impl; + +import cn.hutool.core.collection.ListUtil; +import com.neuhis.his.domain.dto.DeadLock; +import com.neuhis.his.domain.dto.DeadLockRac; +import com.neuhis.his.mapper.OracleSysMapper; +import com.neuhis.his.service.IOracleSysService; +import com.ruoyi.common.annotation.DataSource; +import com.ruoyi.common.enums.DataSourceType; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +@Slf4j +@Service(value = "oracleSysService_pacs") +@DataSource(value = DataSourceType.PACS) +public class OracleSysServicePacsImpl implements IOracleSysService { + @Resource + private OracleSysMapper oracleSysMapper; + @Autowired + private JdbcTemplate jdbcTemplate; + + @Override + public List getDeadLockSessionV1() { + return oracleSysMapper.getDeadLockSessionV1(); + } + + @Override + public List getDeadLockSessionV2Rac() { + List deadLockRacs = oracleSysMapper.getDeadLockSessionV2Rac(); + /*deadLockRacs.add(new DeadLockRac(1, "根锁为此会话杀我KILL ME or igore", "001")); + deadLockRacs.add(new DeadLockRac(5728, "<根锁会话>4903 【SID=4903】的SQL阻塞了本语句[5728]杀掉他", "5728")); + deadLockRacs.add(new DeadLockRac(2222, "<根锁会话>1111 【SID=1111】的SQL阻塞了本语句[2222]杀掉他", "5728")); + deadLockRacs.add(new DeadLockRac(3333, "<根锁会话>1 【SID=1】的SQL阻塞了本语句[3333]杀掉他", "5728"));*/ + return this.findV2DeadLockRacSessionId(deadLockRacs); + } + + @Override + public List getDeadLockSessionV3Slow() { + return oracleSysMapper.getDeadLockSessionV3Slow(); + } + + @Override + public void killSession(String sessionStr) { + try { + if (StringUtils.isNotEmpty(sessionStr)) { + log.info("查杀进程id:" + sessionStr); + oracleSysMapper.killSession(sessionStr); + } + }catch (Exception e){ + log.error("数据库杀死锁异常:"+e.getMessage()); + } + } + + private List findV2DeadLockRacSessionId(List deadLockRacs) { + //找到有问题的进程 + DeadLockRac problematicSession = DeadlockResolver.findProblematicSession(deadLockRacs); + if (problematicSession != null) { + return ListUtil.of(problematicSession); + } + return Lists.newArrayList(); + } +} diff --git a/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/OracleSysServiceWinlisImpl.java b/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/OracleSysServiceWinlisImpl.java new file mode 100644 index 000000000..1f464ebcf --- /dev/null +++ b/ruoyi-admin/src/main/java/com/neuhis/his/service/impl/OracleSysServiceWinlisImpl.java @@ -0,0 +1,69 @@ +package com.neuhis.his.service.impl; + +import cn.hutool.core.collection.ListUtil; +import com.neuhis.his.domain.dto.DeadLock; +import com.neuhis.his.domain.dto.DeadLockRac; +import com.neuhis.his.mapper.OracleSysMapper; +import com.neuhis.his.service.IOracleSysService; +import com.ruoyi.common.annotation.DataSource; +import com.ruoyi.common.enums.DataSourceType; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +@Slf4j +@Service(value = "oracleSysService_winlis") +@DataSource(value = DataSourceType.WINLIS) +public class OracleSysServiceWinlisImpl implements IOracleSysService { + @Resource + private OracleSysMapper oracleSysMapper; + @Autowired + private JdbcTemplate jdbcTemplate; + + @Override + public List getDeadLockSessionV1() { + return oracleSysMapper.getDeadLockSessionV1(); + } + + @Override + public List getDeadLockSessionV2Rac() { + List deadLockRacs = oracleSysMapper.getDeadLockSessionV2Rac(); + /*deadLockRacs.add(new DeadLockRac(1, "根锁为此会话杀我KILL ME or igore", "001")); + deadLockRacs.add(new DeadLockRac(5728, "<根锁会话>4903 【SID=4903】的SQL阻塞了本语句[5728]杀掉他", "5728")); + deadLockRacs.add(new DeadLockRac(2222, "<根锁会话>1111 【SID=1111】的SQL阻塞了本语句[2222]杀掉他", "5728")); + deadLockRacs.add(new DeadLockRac(3333, "<根锁会话>1 【SID=1】的SQL阻塞了本语句[3333]杀掉他", "5728"));*/ + return this.findV2DeadLockRacSessionId(deadLockRacs); + } + + @Override + public List getDeadLockSessionV3Slow() { + return oracleSysMapper.getDeadLockSessionV3Slow(); + } + + @Override + public void killSession(String sessionStr) { + try { + if (StringUtils.isNotEmpty(sessionStr)) { + log.info("查杀进程id:" + sessionStr); + oracleSysMapper.killSession(sessionStr); + } + }catch (Exception e){ + log.error("数据库杀死锁异常:"+e.getMessage()); + } + } + + private List findV2DeadLockRacSessionId(List deadLockRacs) { + //找到有问题的进程 + DeadLockRac problematicSession = DeadlockResolver.findProblematicSession(deadLockRacs); + if (problematicSession != null) { + return ListUtil.of(problematicSession); + } + return Lists.newArrayList(); + } +} diff --git a/ruoyi-admin/src/main/java/com/neuhis/quartz/task/HisTask.java b/ruoyi-admin/src/main/java/com/neuhis/quartz/task/HisTask.java index 389689c1a..45f3e683a 100644 --- a/ruoyi-admin/src/main/java/com/neuhis/quartz/task/HisTask.java +++ b/ruoyi-admin/src/main/java/com/neuhis/quartz/task/HisTask.java @@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import javax.annotation.Resource; import java.util.List; /** @@ -28,8 +29,12 @@ public class HisTask { JobService jobService; @Autowired OracleSlaveDataAutoPushService oracleSlaveDataAutoPushService; - @Autowired + @Resource(name = "oracleSysService_his") private IOracleSysService oracleSysService; + @Resource(name = "oracleSysService_winlis") + private IOracleSysService oracleSysWinlisService; + @Resource(name = "oracleSysService_pacs") + private IOracleSysService oracleSysPacsService; @Autowired private RuoYiConfig ruoYiConfig; @Autowired @@ -66,11 +71,20 @@ public class HisTask { if (ruoYiConfig.isQuzrtzTask()) { log.info("杀oracle死锁开始" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss")); ///List deadLocks = oracleSysService.getDeadLockSessionV1(); - ///deadLocks.forEach(deadLock -> HisTask.this.oracleSysService.killSessionJdbc(deadLock.getSessionStr())); + //deadLocks.forEach(deadLock -> HisTask.this.oracleSysService.killSession(deadLock.getSessionStr())); List sessionV2Rac = oracleSysService.getDeadLockSessionV2Rac(); sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysService.killSession(deadLock.getSessionStr())); - log.info("杀oracle死锁结束,被杀进程数量:" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss")); + log.info("杀lis oracle死锁结束,被杀进程数量:" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss")); + + sessionV2Rac = oracleSysWinlisService.getDeadLockSessionV2Rac(); + sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysWinlisService.killSession(deadLock.getSessionStr())); + log.info("杀winlis oracle死锁结束,被杀进程数量:" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss")); + + + sessionV2Rac = oracleSysPacsService.getDeadLockSessionV2Rac(); + sessionV2Rac.forEach(deadLock -> HisTask.this.oracleSysPacsService.killSession(deadLock.getSessionStr())); + log.info("杀pacs oracle死锁结束,被杀进程数量:" + sessionV2Rac.size() + "," + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss")); } } @@ -85,13 +99,4 @@ public class HisTask { log.info("日志数据删除结束,共删除 "+num+" 条日志。" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss")); } } - - public void winlisCaTask(String testdateLike, Integer limit) - { - if (ruoYiConfig.isQuzrtzTask()) { - log.info("winlisCA数据推送开始" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss")); - winLisService.winlistCaTask(testdateLike,limit); - log.info("winlisCA数据推送结束" + DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss")); - } - } }