spring 动态数据源不起作用
2016-07-21 10:49
453 查看
背景
工程中有两个service,serviceA对应数据源A,serviceB对应数据源B在serviceA.methodA()中调用serviceB.mehtodB()方法,虽然切换数据源aop正确执行了,
但是serviceB.methodB()方法执行时,仍然使用的serviceA的数据源。
动态数据源主要方法类
@Component("datasourceAdvice") public class DatasourceAdvice implements MethodBeforeAdvice { static Logger logger =LoggerFactory.getLogger(DatasourceAdvice.class); @Override public void before(Method method, Object[] args, Object target) throws Throwable { String packName = target.getClass().getPackage().getName(); boolean reportFlag = packName.contains("dataSource2"); if(reportFlag){ logger.info("切换到数据源B"+packName); CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_B); }else{ logger.info("切换到数据源A"+packName); CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_A); } } }
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource{ @Override protected Object determineCurrentLookupKey() { return CustomerContextHolder.getCustomerType(); } }
public class CustomerContextHolder { public static final String DATA_SOURCE_A = "dataSourceOne"; public static final String DATA_SOURCE_B = "dataSourceTwo"; private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setCustomerType(String customerType) { contextHolder.set(customerType); } public static String getCustomerType() { return contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } }
就是说,serviceA.methodA执行时,aop设置了数据源A(
setCustomerType),然后调用
getCustomerType方法。
serviceB.methodB执行时,aop设置了数据源B(
setCustomerType),但是并没有调用
getCustomerType方法,这是为什么?
按理说切换成了数据源B,也应该调用
getCustomerType才对。
分析
serviceA.methodA、serviceB.methodB方法,事务传播属性都是required执行到serviceA.methodA时,由于当前没有事务,所以会创建事务,因为是新事务,所以会获取getDBType,然后get db connection。继续执行,到了serviceB.methodB,切换到数据源B,但是serviceB.methodB事务传播属性是required,并且当前已经有了A创建的事务,所以methodB与methodA使用同一个事务,所以,就不会再getDBType。至此我们分析出,这是事务传播属性捣的鬼。
我们再回头来看,根据需求,methodA与methodB应该是独立的事务,互不影响,并且操作不同数据源。所以把methodB事务传播属性设置为requires_new就可以了。
结论
只有创建新事务时,才会获取数据源,get db connection相关文章推荐
- 深度思考Java成员变量的初始化
- java中静态代码块的用法 static用法详解
- eclipse 设置默认编码为Utf-8
- Eclipse打开WorkSpace已存在工程
- java提高篇(十二)-----代码块
- JAVA实现冒泡排序和二分查找
- 全面了解Java中的内部类和匿名类
- java中String s="abc"及String s=new String("abc")详解
- Java实现推箱子小游戏
- 创建JavaWeb项目时Facets的含义及作用
- Java IO操作——内存操作流{ByteArrayInputStream、ByteArrayOutputStream)
- 山东浪潮齐鲁软件产业股份有限公司-高级Java软件工程师笔试题
- springmvc批量文件打包成zip下载功能
- java IO流
- 02-java-关键词-变量-类型
- 学生学籍管理系统_需求分析
- 正则替换java字符串中的中括号
- 在Ubuntu操作系统中安装eclipse报路径错误怎么解决
- 1.Spring实现数据库的读写分离
- Think in Java 学习