要求几秒钟之内有写请求,哪怕配置读数据库,也要使用master数据库
可以借助spring 的AbstractRoutingDataSource主要实现determineTargetDataSource抽象方法,去获取对应的datasource
public class DynamicDataSource extends AbstractRoutingDataSource {
public static final String DEFAULT_DATA_SOURCE = "defaultDataSource";
public static final List<String> dataSourceNames = new ArrayList<String>();
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceName();
}
public void setTargetDataSources(Map<Object, Object> targetDataSources) {
if (targetDataSources != null) {
Iterator iterator = targetDataSources.keySet().iterator();
while (iterator.hasNext()) {
String name = (String) iterator.next();
if (!DynamicDataSource.DEFAULT_DATA_SOURCE.equals(name)) {
dataSourceNames.add(name);
}
}
}
super.setTargetDataSources(targetDataSources);
}
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
/**
*
* @param dataSourceName
*/
public static void setDataSourceName(String dataSourceName) {
contextHolder.set(dataSourceName);
}
public static String getDataSourceName() {
return contextHolder.get();
}
/**
* 清除只读数据源
*/
public static void clearDataSource() {
contextHolder.remove();
}
/**
* 设置为只读数据源
*/
public static void readDataSource() {
readDataSource(new PollingDataSourceAdapter());
}
public static void readDataSource(DataSourceAdapter adapter){
setDataSourceName(adapter.calculate(DynamicDataSource.dataSourceNames));
}
/**
* 设置为只读数据源
*/
public static void defaultDataSource() {
setDataSourceName(DynamicDataSource.DEFAULT_DATA_SOURCE);
}
}
aspect
public Object switchReadOnlyDataSource(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = null;
try {
if (dataSourceHoldEnabled && DataSourceContextHolder.getDataSourceName() == null) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
if (method.getAnnotation(ReadOnlyDataSource.class) == null||(checkWriteInReadonly&&DistributedContext.getDBWriteRecord().isUpdatedIn(dbSyncSecond))) {//写
DataSourceContextHolder.defaultDataSource();
....
} else {//读
if (dataSourceAdapter == null) {
DataSourceContextHolder.readDataSource();
} else {
DataSourceContextHolder.readDataSource(dataSourceAdapter);
}
}
}
result = joinPoint.proceed();
} finally {
if (flag) {
DataSourceContextHolder.clearDataSource();
}
}
return result;
}
参考:http://www.cnblogs.com/surge/p/3582248.html