spring配置多数据源涉及事务无法切换解决方案(绝对有效)

最近在做的项目需要操作两个数据源,并且是一个service需要同时调用两个数据源,刚开始按照网上说的配置通过切面操作AbstractRoutingDataSource这个类,发现单独去调用每一个数据源可以灵活切换,后来涉及事务一个service调用两个数据源就发现动态数据源无法切换了,琢磨了很久,终于找到原因。

问题根源:

spring涉及事务的代码调用顺序:

service注解上@transactional-->TransactionInterceptor.interpter()-->TransactionAspectSupport.createTransactionIfNecessary()-->AbstractPlatformTransactionManager.getTransaction()-->DataSourceTransactionManager.doBegin()-->AbstractRoutingDataSource.determineTargetDataSource()[lookupKey==null去拿默认的Datasource, 不为空则使用获取到的连接]-->DataSourceTransactionManager.setTransactional()[将连接设置到TransactionUtils的threadLocal中]--->Repository@Annotation-->执行一般调用链, 问题在于SpringManagedTransaction.getConnection()-->openConnection()-->DataSourceUtils.getConnection()-->TransactionSynchronizationManager.getResource(dataSource)不为空[从TransactionUtils的threadLocal中获取数据源], 所以不会再去调用DynamicDataSource去获取数据源

需要解决问题:在操作完数据库后把threadLocal中的数据源清除!

解决方案:

1.先写一个动态数据源继承AbstractRoutingDataSource

package com.dataSource;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 动态数据源
 * @author 張丶張張張某人
 *
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
	
	/**
	 * 数据源标识,保存在线程变量中,避免多线程操作数据源时互相干扰
	 */
	private static final ThreadLocal<String> key = new ThreadLocal<String>();

	@Override
	protected Object determineCurrentLookupKey() {
		return key.get();
	}
	
	
	
	/**
	 * 设置数据源
	 * @param dataSource 数据源名称
	 */
	public static void setDataSource(String dataSource){
		key.set(dataSource);
	}


	/**
	 * 获取数据源
	 * @return
	 */
	public static String getDatasource() {
		return key.get();
	}

	/**
	 * 清除数据源
	 */
	public static void clearDataSource(){
		key.remove();
	}

}

2.新建一个@DataSource注解用于aop切换数据源

package com.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 定义数据源切换
 * @author 張丶張張張某人
 *
 */
@Documented
@Target({ElementType.TYP
  • 5
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 58
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 58
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值