com.lsq.springboot.datasource.starter.MultiDataSourceContextHolder Maven / Gradle / Ivy
/*
* Copyright 2018 the organization loushi135
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.lsq.springboot.datasource.starter;
import java.util.concurrent.LinkedBlockingDeque;
/**
* 核心基于ThreadLocal的切换数据源工具类
*
* @author TaoYu Kanyuxia
* @since 1.0.0
*/
public final class MultiDataSourceContextHolder {
/**
* 为什么要用链表存储(准确的是栈)
*
* 为了支持嵌套切换,如ABC三个service都是不同的数据源
* 其中A的某个业务要调B的方法,B的方法需要调用C的方法。一级一级调用切换,形成了链。
* 传统的只设置当前线程的方式不能满足此业务需求,必须模拟栈,后进先出。
*
*/
@SuppressWarnings("unchecked")
private static final ThreadLocal> LOOKUP_KEY_HOLDER = new ThreadLocal() {
@Override
protected Object initialValue() {
return new LinkedBlockingDeque();
}
};
private MultiDataSourceContextHolder() {
}
/**
* 获得当前线程数据源
*
* @return 数据源名称
*/
public static String getDataSourceLookupKey() {
LinkedBlockingDeque deque = LOOKUP_KEY_HOLDER.get();
return deque.isEmpty() ? null : deque.getFirst();
}
/**
* 设置当前线程数据源
*
* @param dataSourceLookupKey 数据源名称
*/
public static void setDataSourceLookupKey(String dataSourceLookupKey) {
LOOKUP_KEY_HOLDER.get().addFirst(dataSourceLookupKey);
}
/**
* 清空当前线程数据源
*
* 如果当前线程是连续切换数据源
* 只会移除掉当前线程的数据源名称
*
*/
public static void clearDataSourceLookupKey() {
LinkedBlockingDeque deque = LOOKUP_KEY_HOLDER.get();
if (deque.isEmpty()) {
LOOKUP_KEY_HOLDER.remove();
} else {
deque.pollFirst();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy