【动态数据源切换失败】由于事务@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";
}
【动态数据源切换失败】由于事务@Transactional注解导致动态数据源切换失效的问题的更多相关文章
- 对于spring中事务@Transactional注解的理解
现在spring的配置都喜欢用注解,这边就说下@Transactional 一.如何开启@Transactional支持 要使用@Transactional,spring的配置文件applicatio ...
- 分析spring事务@Transactional注解在同一个类中的方法之间调用不生效的原因及解决方案
问题: 在Spring管理的项目中,方法A使用了Transactional注解,试图实现事务性.但当同一个class中的方法B调用方法A时,会发现方法A中的异常不再导致回滚,也即事务失效了. 当这个方 ...
- 事务@Transactional注解的属性
事务的传播行为 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播.例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行.事务的传播行为可以由传播属性指定.Sprin ...
- 一口气说出 6种,@Transactional注解的失效场景
整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 一口气说出 9种 分布式ID生成方式,面试官有点懵了 面试总被问 ...
- @Transactional注解的失效场景
一口气说出 6种,@Transactional注解的失效场景 计算机java编程 发布时间: 20-03-1912:35优质科技领域创作者 引言 昨天公众号粉丝咨询了一个问题,说自己之前面试被问@Tr ...
- Java基础加强-(注解,动态代理,类加载器,servlet3.0新特性)
1. Annotation注解 1.1. Annotation概述 Annotation是JDK 5.0以后提供对元数据的支持,可以在编译.加载和运行时被读取,并执行相应的处理.所谓Annota ...
- Spring 多数据源 @Transactional 注解事务管理
在 Spring,MyBatis 下两个数据源,通过 @Transactional 注解 配置简单的事务管理 spring-mybatis.xml <!--******************* ...
- Spring动态切换多数据源事务开启后,动态数据源切换失效解决方案
关于某操作中开启事务后,动态切换数据源机制失效的问题,暂时想到一个取巧的方法,在Spring声明式事务配置中,可对不改变数据库数据的方法采用不支持事务的配置,如下: 对单纯查询数据的操作设置为不支持事 ...
- AOP获取方法注解实现动态切换数据源
AOP获取方法注解实现动态切换数据源(以下方式尚未经过测试,仅提供思路) ------ 自定义一个用于切换数据源的注解: package com.xxx.annotation; import org. ...
随机推荐
- Python插入排序
升序 import random l = [] for i in range(8): l.append(random.randint(0,9)) print(l) for cur in range(1 ...
- mpvue 开发微信小程序搭建项目
首先 mpvue 是一款基于vue的框架,mpvue 修改了 Vue.js 的 runtime 和 compile 实现,可以运行在小程序的环境中. 第一步:安装 vue-cli vue-cli是vu ...
- SVN同步方式举例 FreeBSD
FreeBSD base 默认安装了svnlite 不需要单独安装SVN 软件 svnlite co svn.freebsd.org/ports/head/ /usr/local/ports -r5 ...
- [MongoDB知识体系] 一文全面总结MongoDB知识体系
MongoDB教程 - Mongo知识体系详解 本系列将给大家构建MongoDB全局知识体系.@pdai MongoDB教程 - Mongo知识体系详解 知识体系 学习要点 学习资料 官网资料 入门系 ...
- python基础学习之简化占位符和格式化的概念
简化版占位符有哪些? %s 字符串占位符,代表该位置有一个字符串待替换(万能) %d 数字占位符,代表该位置有一个数字待替换 %f 同上,这里是浮点数,float[默认保留6位小数] % ...
- ES6学习笔记(3)- 对象的功能性扩展
一.什么是对象字面量 对象字面量就是创建对象(Object)的一种简单容易理解的方式,再通俗点就是所谓的键值对的集合.举个简单的例子: let book = { name: 'JavaScript', ...
- Web实验报告
- 对控制器类型“StudentController”的操作“Edit”的当前请求在下列操作方法之间不明确:
"/"应用程序中的服务器错误. 对控制器类型"StudentController"的操作"Edit"的当前请求在下列操作方法之间不明确:类型 ...
- effective解读-第一条 静态工厂创建对象代替构造器
好处 有名称,能见名知意.例如BigInteger的probablePrime方法 享元模式.单例模式中使用 享元模式:创建对象代价很高,重复调用已有对象,例如数据库连接等.享元模式是单例模式的一个拓 ...
- python进阶(一)变量与数据类型、python之禅
一.变量: 1.变量组成:由数据.字母与下划线组合 2.不能以数字开头 3.python关键字与函数名不能作为变量名 4.当字符串变量中包含引号时,可使用单引号与双引号进行区分,或转义 print(& ...