• 【动态数据源切换失败】由于事务@Transactional注解导致动态数据源切换失效的问题


    不多BB,直接上代码:

    public class DataSourceKey {
    
        /**
         * 用户数据源
         */
        public final static String USER = "userDataSource";
    
    
        /**
         * 报表数据源
         */
        public final static String REPORT = "reportDataSource";
    
    
        /**
         * 所有数据源的集合
         */
        final static List<String> SOURCES = ImmutableList.of(USER, REPORT);
    
    
        /**
         * 根据包名找到数据源, 多数据源的前缀不能存在相同的。 例: user -> userDataSource
         *
         * @param pack 包名
         * @return 数据源名
         */
        public static String getDataSourceKey(String pack) {
            return SOURCES.stream().filter(s -> s.startsWith(pack)).findFirst().orElse(USER);
        }
    }
    @Component
    @Aspect
    @Order(-1)
    @Slf4j
    public class DynamicDataSourceAspect {
    
        @Pointcut("execution(* com.in.g.data.mapper..*.*(..))")
        public void dataSourcePointcut() {
        }
    
        @Before("dataSourcePointcut()")
        public void doBefore(JoinPoint point) throws Throwable {
            log.debug("切换数据源开始。。。。。。。。。。。。");
            Package pack = point.getSignature().getDeclaringType().getPackage();
            String str = StringUtils.substringAfterLast(pack.getName(), ".");
            String dataSourceKey = DataSourceKey.getDataSourceKey(str);
            DynamicDataSourceHolder.set(dataSourceKey);
            log.debug("切换数据源成功,当前数据源:{}", dataSourceKey);
        }
    
        @After("dataSourcePointcut()")
        public void doAfterReturning() throws Throwable {
            DynamicDataSourceHolder.clear();
        }
    
    }
    /**
     * 动态数据源持有者
     */
    public class DynamicDataSourceHolder {
    
        public static ThreadLocal<String> keyHolder = new ThreadLocal<>();
    
        public static void clear() {
            keyHolder.remove();
        }
    
        public static void set(String key) {
            keyHolder.set(key);
        }
    
        public static String get() {
            return keyHolder.get();
        }
    
    }
    /**
     * 动态数据源配置
     */
    public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
        @Override
        protected Object determineCurrentLookupKey() {
            return DynamicDataSourceHolder.get();
        }
    }
    //正确的代码   --这里偷懒了,直接controller调用dao层
    @GetMapping("/testdb") public String testDateSources(){
         //缩小事务的范围 add();
    rptFieldMapper.selectxxxx(); return "sss"; } @Transactional(rollbackFor = Exception.class) public void add() {
         userMapper.insertXXXX(xxxx);
     }
        //错误的代码,@Transactional注解会导致 数据源切换失败
        @GetMapping("/testdb")
        @Transactional(rollbackFor = Exception.class)
        public String testDateSources(){
      
            userMapper.insertXXXX(xxxx);
    
            rptFieldMapper.selectXXXX();
            
    
            return "sss";
        }
  • 相关阅读:
    开源项目
    分享知识 学无止境 只做正确的事 伸出援助之手
    公开支持与鼓励,私下质疑与建议(转)
    天使投资人给阿里新贵们的一些建议(转)
    沟通中“倾听”的五个层次
    intent
    SafeNet推出行业首款白盒password软件保护解决方式
    应用系统设计思考
    常见的几种RuntimeException
    ASP.NETserver控件使用之Reportviewer 报表
  • 原文地址:https://www.cnblogs.com/july-sunny/p/12518233.html
Copyright © 2020-2023  润新知