Browse Source

多数据源切换问题

baiying 1 week ago
parent
commit
1230c6c3c9

+ 0 - 6
canal-console/src/main/java/com/retdata/canal/CannalClient.java

@@ -10,10 +10,7 @@ import com.alibaba.otter.canal.protocol.CanalEntry;
 import com.alibaba.otter.canal.protocol.Message;
 import com.retdata.canal.handler.AbstractCanalDbHandler;
 import com.ruoyi.common.enums.DataSourceEnum;
-import com.ruoyi.common.enums.DataSourceType;
-import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -299,7 +296,6 @@ public class CannalClient {
                         log.warn("应用正在关闭,跳过处理: {}", tableName);
                         break;
                     }
-                    DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.CSO.name());
                     canalDbHandler.processRow(rowData, eventType, dataSourceEnum);
                 }catch (Exception e){
                     if (!running) {
@@ -310,8 +306,6 @@ public class CannalClient {
                     }
                 } finally {
                     log.info("{} 结束处理", tableName);
-
-                    DynamicDataSourceContextHolder.clearDataSourceType();
                 }
             }
         }

+ 7 - 35
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataSourceAspect.java

@@ -2,9 +2,7 @@ package com.ruoyi.framework.aspectj;
 
 import java.util.Objects;
 import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.annotation.*;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -34,39 +32,13 @@ public class DataSourceAspect
 
     }
 
-    @Around("dsPointCut()")
-    public Object around(ProceedingJoinPoint point) throws Throwable
-    {
-        DataSource dataSource = getDataSource(point);
-
-        if (StringUtils.isNotNull(dataSource))
-        {
-            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
-        }
-
-        try
-        {
-            return point.proceed();
-        }
-        finally
-        {
-            // 销毁数据源 在执行方法之后
-            DynamicDataSourceContextHolder.clearDataSourceType();
-        }
+    @Before(value="dsPointCut() && @within(dataSource))", argNames="dataSource")
+    public void before(DataSource dataSource){
+        DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
     }
 
-    /**
-     * 获取需要切换的数据源
-     */
-    public DataSource getDataSource(ProceedingJoinPoint point)
-    {
-        MethodSignature signature = (MethodSignature) point.getSignature();
-        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
-        if (Objects.nonNull(dataSource))
-        {
-            return dataSource;
-        }
-
-        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
+    @After("dsPointCut()")
+    public void after() {
+        DynamicDataSourceContextHolder.clearDataSourceType();
     }
 }

+ 9 - 2
ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSource.java

@@ -1,6 +1,7 @@
 package com.ruoyi.framework.datasource;
 
 import java.util.Map;
+import java.util.Stack;
 import javax.sql.DataSource;
 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 
@@ -11,6 +12,7 @@ import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
  */
 public class DynamicDataSource extends AbstractRoutingDataSource
 {
+
     public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
     {
         super.setDefaultTargetDataSource(defaultTargetDataSource);
@@ -18,9 +20,14 @@ public class DynamicDataSource extends AbstractRoutingDataSource
         super.afterPropertiesSet();
     }
 
+    /**
+     * determineCurrentLookupKey
+     * @return
+     *
+     * @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#determineCurrentLookupKey()
+     */
     @Override
-    protected Object determineCurrentLookupKey()
-    {
+    protected Object determineCurrentLookupKey() {
         return DynamicDataSourceContextHolder.getDataSourceType();
     }
 }

+ 22 - 5
ruoyi-framework/src/main/java/com/ruoyi/framework/datasource/DynamicDataSourceContextHolder.java

@@ -3,6 +3,8 @@ package com.ruoyi.framework.datasource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Stack;
+
 /**
  * 数据源切换处理
  * 
@@ -16,15 +18,20 @@ public class DynamicDataSourceContextHolder
      * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
      * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
      */
-    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
+
+    private static final ThreadLocal<Stack<String>> DATA_SOURCE_KEY = new InheritableThreadLocal<>();
 
     /**
      * 设置数据源的变量
      */
     public static void setDataSourceType(String dsType)
     {
-        log.info("切换到{}数据源", dsType);
-        CONTEXT_HOLDER.set(dsType);
+        Stack<String> stack = DATA_SOURCE_KEY.get();
+        if (stack == null) {
+            stack = new Stack<>();
+            DATA_SOURCE_KEY.set(stack);
+        }
+        stack.push(dsType);
     }
 
     /**
@@ -32,7 +39,11 @@ public class DynamicDataSourceContextHolder
      */
     public static String getDataSourceType()
     {
-        return CONTEXT_HOLDER.get();
+        Stack<String> stack = DATA_SOURCE_KEY.get();
+        if (stack != null) {
+            return stack.peek();
+        }
+        return null;
     }
 
     /**
@@ -40,6 +51,12 @@ public class DynamicDataSourceContextHolder
      */
     public static void clearDataSourceType()
     {
-        CONTEXT_HOLDER.remove();
+        Stack<String> stack = DATA_SOURCE_KEY.get();
+        if (stack != null) {
+            stack.pop();
+            if (stack.isEmpty()) {
+                DATA_SOURCE_KEY.remove();
+            }
+        }
     }
 }

+ 1 - 1
yaoyi-bi/src/main/java/com/retdata/yaoyibi/service/impl/WmScorePackageServiceImpl.java

@@ -566,7 +566,7 @@ public class WmScorePackageServiceImpl extends ServiceImpl<WmScorePackageMapper,
                 columnNo = 0;
                 // "签约企业ID", "签约企业名称", "企业类型", "签约产品", "签约灵工状态",
                 if (exportRecord.getRootDept() != null) {
-                    row.createCell(columnNo++).setCellValue(exportRecord.getRootDept().getDeptId().toString());
+                    row.createCell(columnNo++).setCellValue(String.valueOf(exportRecord.getRootDept().getDeptId()));
                     row.createCell(columnNo++).setCellValue(exportRecord.getRootDept().getName());
                     row.createCell(columnNo++).setCellValue(SYS_DEPT_LEVEL_DICT.get(exportRecord.getRootDept().getLevel()));
                     row.createCell(columnNo++).setCellValue(deptSignProducts.get(exportRecord.getRootDept().getDeptId()));