紧急修复数据源切换失效的问题

This commit is contained in:
Dftre 2024-05-30 08:52:22 +08:00
parent 8f04b9e5b8
commit 1c5b40771d
3 changed files with 63 additions and 110 deletions

View File

@ -12,10 +12,10 @@ spring:
# 从库数据源 # 从库数据源
slave: slave:
# 从数据源开关/默认关闭 # 从数据源开关/默认关闭
enabled: true enabled: false
url: url: jdbc:mysql://127.0.0.1/ruoyi?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: username: root
password: password: 123456
# 初始连接数 # 初始连接数
initialSize: 5 initialSize: 5

View File

@ -150,7 +150,7 @@ public class MyBatisConfig {
Map<Object, SqlSessionFactory> sqlSessionFactoryMap) { Map<Object, SqlSessionFactory> sqlSessionFactoryMap) {
try { try {
SqlSessionFactory factorySlave = SpringUtils.getBean(sqlSessionFactoryName); SqlSessionFactory factorySlave = SpringUtils.getBean(sqlSessionFactoryName);
sqlSessionFactoryMap.put(dataSourceType, factorySlave); sqlSessionFactoryMap.put(dataSourceType.name(), factorySlave);
} catch (Exception e) { } catch (Exception e) {
logger.error("Failed to register a SqlSessionFactory:{}", sqlSessionFactoryName); logger.error("Failed to register a SqlSessionFactory:{}", sqlSessionFactoryName);
} }

View File

@ -27,8 +27,7 @@ import org.springframework.dao.support.PersistenceExceptionTranslator;
* *
* @author ruoyi * @author ruoyi
*/ */
public class DynamicSqlSessionTemplate extends SqlSessionTemplate public class DynamicSqlSessionTemplate extends SqlSessionTemplate {
{
private final SqlSessionFactory sqlSessionFactory; private final SqlSessionFactory sqlSessionFactory;
private final ExecutorType executorType; private final ExecutorType executorType;
private final SqlSession sqlSessionProxy; private final SqlSession sqlSessionProxy;
@ -36,20 +35,17 @@ public class DynamicSqlSessionTemplate extends SqlSessionTemplate
private Map<Object, SqlSessionFactory> targetSqlSessionFactorys; private Map<Object, SqlSessionFactory> targetSqlSessionFactorys;
private SqlSessionFactory defaultTargetSqlSessionFactory; private SqlSessionFactory defaultTargetSqlSessionFactory;
public DynamicSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) public DynamicSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
{
this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType()); this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
} }
public DynamicSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) public DynamicSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {
{
this(sqlSessionFactory, executorType, new MyBatisExceptionTranslator( this(sqlSessionFactory, executorType, new MyBatisExceptionTranslator(
sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true)); sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true));
} }
public DynamicSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, public DynamicSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
PersistenceExceptionTranslator exceptionTranslator) PersistenceExceptionTranslator exceptionTranslator) {
{
super(sqlSessionFactory, executorType, exceptionTranslator); super(sqlSessionFactory, executorType, exceptionTranslator);
this.sqlSessionFactory = sqlSessionFactory; this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType; this.executorType = executorType;
@ -59,118 +55,100 @@ public class DynamicSqlSessionTemplate extends SqlSessionTemplate
this.defaultTargetSqlSessionFactory = sqlSessionFactory; this.defaultTargetSqlSessionFactory = sqlSessionFactory;
} }
public void setTargetSqlSessionFactorys(Map<Object, SqlSessionFactory> targetSqlSessionFactorys) public void setTargetSqlSessionFactorys(Map<Object, SqlSessionFactory> targetSqlSessionFactorys) {
{
this.targetSqlSessionFactorys = targetSqlSessionFactorys; this.targetSqlSessionFactorys = targetSqlSessionFactorys;
} }
public void setDefaultTargetSqlSessionFactory(SqlSessionFactory defaultTargetSqlSessionFactory) public void setDefaultTargetSqlSessionFactory(SqlSessionFactory defaultTargetSqlSessionFactory) {
{
this.defaultTargetSqlSessionFactory = defaultTargetSqlSessionFactory; this.defaultTargetSqlSessionFactory = defaultTargetSqlSessionFactory;
} }
@Override @Override
public SqlSessionFactory getSqlSessionFactory() public SqlSessionFactory getSqlSessionFactory() {
{
SqlSessionFactory targetSqlSessionFactory = targetSqlSessionFactorys SqlSessionFactory targetSqlSessionFactory = targetSqlSessionFactorys
.get(DynamicDataSourceContextHolder.getDataSourceType()); .get(DynamicDataSourceContextHolder.getDataSourceType());
if (targetSqlSessionFactory != null) if (targetSqlSessionFactory != null) {
{
return targetSqlSessionFactory; return targetSqlSessionFactory;
} } else if (defaultTargetSqlSessionFactory != null) {
else if (defaultTargetSqlSessionFactory != null)
{
return defaultTargetSqlSessionFactory; return defaultTargetSqlSessionFactory;
} }
return this.sqlSessionFactory; return this.sqlSessionFactory;
} }
@Override @Override
public Configuration getConfiguration() public Configuration getConfiguration() {
{
return this.getSqlSessionFactory().getConfiguration(); return this.getSqlSessionFactory().getConfiguration();
} }
public ExecutorType getExecutorType() public ExecutorType getExecutorType() {
{
return this.executorType; return this.executorType;
} }
public PersistenceExceptionTranslator getPersistenceExceptionTranslator() public PersistenceExceptionTranslator getPersistenceExceptionTranslator() {
{
return this.exceptionTranslator; return this.exceptionTranslator;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public <T> T selectOne(String statement) public <T> T selectOne(String statement) {
{ return this.sqlSessionProxy.<T>selectOne(statement);
return this.sqlSessionProxy.<T> selectOne(statement);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public <T> T selectOne(String statement, Object parameter) public <T> T selectOne(String statement, Object parameter) {
{ return this.sqlSessionProxy.<T>selectOne(statement, parameter);
return this.sqlSessionProxy.<T> selectOne(statement, parameter);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public <K, V> Map<K, V> selectMap(String statement, String mapKey) public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
{ return this.sqlSessionProxy.<K, V>selectMap(statement, mapKey);
return this.sqlSessionProxy.<K, V> selectMap(statement, mapKey);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
{ return this.sqlSessionProxy.<K, V>selectMap(statement, parameter, mapKey);
return this.sqlSessionProxy.<K, V> selectMap(statement, parameter, mapKey);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
{ return this.sqlSessionProxy.<K, V>selectMap(statement, parameter, mapKey, rowBounds);
return this.sqlSessionProxy.<K, V> selectMap(statement, parameter, mapKey, rowBounds);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public <E> List<E> selectList(String statement) public <E> List<E> selectList(String statement) {
{ return this.sqlSessionProxy.<E>selectList(statement);
return this.sqlSessionProxy.<E> selectList(statement);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public <E> List<E> selectList(String statement, Object parameter) public <E> List<E> selectList(String statement, Object parameter) {
{ return this.sqlSessionProxy.<E>selectList(statement, parameter);
return this.sqlSessionProxy.<E> selectList(statement, parameter);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
{ return this.sqlSessionProxy.<E>selectList(statement, parameter, rowBounds);
return this.sqlSessionProxy.<E> selectList(statement, parameter, rowBounds);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public void select(String statement, ResultHandler handler) public void select(String statement, ResultHandler handler) {
{
this.sqlSessionProxy.select(statement, handler); this.sqlSessionProxy.select(statement, handler);
} }
@ -178,8 +156,7 @@ public class DynamicSqlSessionTemplate extends SqlSessionTemplate
* {@inheritDoc} * {@inheritDoc}
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public void select(String statement, Object parameter, ResultHandler handler) public void select(String statement, Object parameter, ResultHandler handler) {
{
this.sqlSessionProxy.select(statement, parameter, handler); this.sqlSessionProxy.select(statement, parameter, handler);
} }
@ -187,120 +164,105 @@ public class DynamicSqlSessionTemplate extends SqlSessionTemplate
* {@inheritDoc} * {@inheritDoc}
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
{
this.sqlSessionProxy.select(statement, parameter, rowBounds, handler); this.sqlSessionProxy.select(statement, parameter, rowBounds, handler);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int insert(String statement) public int insert(String statement) {
{
return this.sqlSessionProxy.insert(statement); return this.sqlSessionProxy.insert(statement);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int insert(String statement, Object parameter) public int insert(String statement, Object parameter) {
{
return this.sqlSessionProxy.insert(statement, parameter); return this.sqlSessionProxy.insert(statement, parameter);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int update(String statement) public int update(String statement) {
{
return this.sqlSessionProxy.update(statement); return this.sqlSessionProxy.update(statement);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int update(String statement, Object parameter) public int update(String statement, Object parameter) {
{
return this.sqlSessionProxy.update(statement, parameter); return this.sqlSessionProxy.update(statement, parameter);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int delete(String statement) public int delete(String statement) {
{
return this.sqlSessionProxy.delete(statement); return this.sqlSessionProxy.delete(statement);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public int delete(String statement, Object parameter) public int delete(String statement, Object parameter) {
{
return this.sqlSessionProxy.delete(statement, parameter); return this.sqlSessionProxy.delete(statement, parameter);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public <T> T getMapper(Class<T> type) public <T> T getMapper(Class<T> type) {
{
return getConfiguration().getMapper(type, this); return getConfiguration().getMapper(type, this);
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void commit() public void commit() {
{
throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession"); throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void commit(boolean force) public void commit(boolean force) {
{
throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession"); throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void rollback() public void rollback() {
{
throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession"); throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void rollback(boolean force) public void rollback(boolean force) {
{
throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession"); throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void close() public void close() {
{
throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession"); throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession");
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public void clearCache() public void clearCache() {
{
this.sqlSessionProxy.clearCache(); this.sqlSessionProxy.clearCache();
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public Connection getConnection() public Connection getConnection() {
{
return this.sqlSessionProxy.getConnection(); return this.sqlSessionProxy.getConnection();
} }
@ -309,48 +271,39 @@ public class DynamicSqlSessionTemplate extends SqlSessionTemplate
* *
* @since 1.0.2 * @since 1.0.2
*/ */
public List<BatchResult> flushStatements() public List<BatchResult> flushStatements() {
{
return this.sqlSessionProxy.flushStatements(); return this.sqlSessionProxy.flushStatements();
} }
/** /**
* Proxy needed to route MyBatis method calls to the proper SqlSession got from Spring's Transaction Manager It also * Proxy needed to route MyBatis method calls to the proper SqlSession got from
* unwraps exceptions thrown by {@code Method#invoke(Object, Object...)} to pass a {@code PersistenceException} to * Spring's Transaction Manager It also
* unwraps exceptions thrown by {@code Method#invoke(Object, Object...)} to pass
* a {@code PersistenceException} to
* the {@code PersistenceExceptionTranslator}. * the {@code PersistenceExceptionTranslator}.
*/ */
private class SqlSessionInterceptor implements InvocationHandler private class SqlSessionInterceptor implements InvocationHandler {
{ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
final SqlSession sqlSession = getSqlSession(DynamicSqlSessionTemplate.this.getSqlSessionFactory(), final SqlSession sqlSession = getSqlSession(DynamicSqlSessionTemplate.this.getSqlSessionFactory(),
DynamicSqlSessionTemplate.this.executorType, DynamicSqlSessionTemplate.this.exceptionTranslator); DynamicSqlSessionTemplate.this.executorType, DynamicSqlSessionTemplate.this.exceptionTranslator);
try try {
{
Object result = method.invoke(sqlSession, args); Object result = method.invoke(sqlSession, args);
if (!isSqlSessionTransactional(sqlSession, DynamicSqlSessionTemplate.this.getSqlSessionFactory())) if (!isSqlSessionTransactional(sqlSession, DynamicSqlSessionTemplate.this.getSqlSessionFactory())) {
{
sqlSession.commit(true); sqlSession.commit(true);
} }
return result; return result;
} } catch (Throwable t) {
catch (Throwable t)
{
Throwable unwrapped = unwrapThrowable(t); Throwable unwrapped = unwrapThrowable(t);
if (DynamicSqlSessionTemplate.this.exceptionTranslator != null if (DynamicSqlSessionTemplate.this.exceptionTranslator != null
&& unwrapped instanceof PersistenceException) && unwrapped instanceof PersistenceException) {
{
Throwable translated = DynamicSqlSessionTemplate.this.exceptionTranslator Throwable translated = DynamicSqlSessionTemplate.this.exceptionTranslator
.translateExceptionIfPossible((PersistenceException) unwrapped); .translateExceptionIfPossible((PersistenceException) unwrapped);
if (translated != null) if (translated != null) {
{
unwrapped = translated; unwrapped = translated;
} }
} }
throw unwrapped; throw unwrapped;
} } finally {
finally
{
closeSqlSession(sqlSession, DynamicSqlSessionTemplate.this.getSqlSessionFactory()); closeSqlSession(sqlSession, DynamicSqlSessionTemplate.this.getSqlSessionFactory());
} }
} }