不多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";
}

【动态数据源切换失败】由于事务@Transactional注解导致动态数据源切换失效的问题的更多相关文章

  1. 对于spring中事务@Transactional注解的理解

    现在spring的配置都喜欢用注解,这边就说下@Transactional 一.如何开启@Transactional支持 要使用@Transactional,spring的配置文件applicatio ...

  2. 分析spring事务@Transactional注解在同一个类中的方法之间调用不生效的原因及解决方案

    问题: 在Spring管理的项目中,方法A使用了Transactional注解,试图实现事务性.但当同一个class中的方法B调用方法A时,会发现方法A中的异常不再导致回滚,也即事务失效了. 当这个方 ...

  3. 事务@Transactional注解的属性

    事务的传播行为 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播.例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行.事务的传播行为可以由传播属性指定.Sprin ...

  4. 一口气说出 6种,@Transactional注解的失效场景

    整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 一口气说出 9种 分布式ID生成方式,面试官有点懵了 面试总被问 ...

  5. @Transactional注解的失效场景

    一口气说出 6种,@Transactional注解的失效场景 计算机java编程 发布时间: 20-03-1912:35优质科技领域创作者 引言 昨天公众号粉丝咨询了一个问题,说自己之前面试被问@Tr ...

  6. Java基础加强-(注解,动态代理,类加载器,servlet3.0新特性)

    1.   Annotation注解 1.1.  Annotation概述 Annotation是JDK 5.0以后提供对元数据的支持,可以在编译.加载和运行时被读取,并执行相应的处理.所谓Annota ...

  7. Spring 多数据源 @Transactional 注解事务管理

    在 Spring,MyBatis 下两个数据源,通过 @Transactional 注解 配置简单的事务管理 spring-mybatis.xml <!--******************* ...

  8. Spring动态切换多数据源事务开启后,动态数据源切换失效解决方案

    关于某操作中开启事务后,动态切换数据源机制失效的问题,暂时想到一个取巧的方法,在Spring声明式事务配置中,可对不改变数据库数据的方法采用不支持事务的配置,如下: 对单纯查询数据的操作设置为不支持事 ...

  9. AOP获取方法注解实现动态切换数据源

    AOP获取方法注解实现动态切换数据源(以下方式尚未经过测试,仅提供思路) ------ 自定义一个用于切换数据源的注解: package com.xxx.annotation; import org. ...

随机推荐

  1. 图文详解:阿里宠儿【小兔】RabbitMQ的养成攻略

  2. 微信小程序自定义头部导航栏

    <!--index.wxml--> <view> <navbar id='index_header' background='{{background}}' pageNa ...

  3. golang操作mysql2

    目录 Go操作MySQL 连接 下载依赖 使用MySQL驱动 初始化连接 SetMaxOpenConns SetMaxIdleConns CRUD 建库建表 查询 单行查询 多行查询 插入数据 更新数 ...

  4. Java-for循环打印九九乘法表

    Java打印九九乘法表 public class forDemo04 { public static void main(String[] args) { //练习3:打印九九乘法表 /* 1*1=1 ...

  5. calcite 概念和架构

    1. 前言 Flink使用Calcite构造SQL引擎,那么他们 是怎么合作的? drill, hive,storm 和其他的一干apache 大数据引擎也用calcite , 那么对于同一个sql  ...

  6. 02----python入门----基本数据类型

    关于数据分类依据 一.数字型(int) Python可以处理任意大小的正负整数,但是实际中跟我们计算机的内存有关,在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,在64位系 ...

  7. rest-framework routers

    路由器 资源路由可以让你快速声明所有给定的足智多谋的控制器的共同路线.相反,宣布独立的路线索引的......一个足智多谋的路线宣称他们在一个单一的代码行. - Ruby on Rails的文档 一些W ...

  8. 优化自动化测试流程,使用 flask 开发一个 toy jenkins工具

    1.自动化 某一天你入职了一家高大上的科技公司,开心的做着软件测试的工作,每天点点点,下班就走,晚上陪女朋友玩王者,生活很惬意. 但是美好时光一般不长,这种生活很快被女主管打破.为了提升公司测试效率, ...

  9. Java基础:重文本markdown

    说一说markdown 前言 在系统学习Java等开发语言之前,我们应该养成写"日记"的习惯,也就是写博客:写博客的地方有博客园,csdn等.而写博客又得知道markdown重文本 ...

  10. CentOS 8.3安装MySQL 8.0.21后无法登录管理数据库

    安装mysql后登录不了,提示: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) ...