您的位置:首页 > 编程语言 > Java开发

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: