解决多数据源自动切换不成功问题

产生原因

  1. 代理模式中真实对象方法调用方法不会走代理对象,因此类似于@DS注解使用AOP切面进行数据源的切换,在方法调用方法是不会成功的

解决办法

  1. 原理:通过修改本地线程变量中的数据源栈,来进行数据源的切换
  2. 本实例使用@DS,其他动态数据源(自定义动态数据源)逻辑类似
  3. 封装的手动切换数据源工具类
  • 自定义一个SmallConsumer注解,主要是填充无参回调函数接口
@FunctionalInterface
public interface SmallConsumer {
    /**
     * 接收方法
     */
    void accept();
    /**
     * 用于递归调用
     * @param after
     * @return
     */
    default SmallConsumer andThen(SmallConsumer after) {
        Objects.requireNonNull(after);
        return () -> {
            accept();
            after.accept();
        };
    }
}
  • 编写手动切换数据源工具类,实际就是操作本地线程变量
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;

@Component
@Slf4j
public class ChooseDsUtil {
    private final static String masterDB = "master";
    private final static String slaveDB = "slave";
    @Resource
    private ApplicationContext applicationContext;
    /**
     * 手动切换到master执行
     * 例子:chooseDsUtil.masterExec(() -> memberDao.insert(userPo));
     * @param execConsumer
     */
    public void masterExec(SmallConsumer execConsumer) {
        try {
            DynamicDataSourceContextHolder.push(masterDB);
            execConsumer.accept();
        } finally {
            DynamicDataSourceContextHolder.poll();
        }
    }
    /**
     * 手动切换到slave执行
     * 例子:chooseDsUtil.slaveExec(() -> getUserById("1"));
     * @param execConsumer
     */
    public void slaveExec(SmallConsumer execConsumer) {
        try {
            DynamicDataSourceContextHolder.push(slaveDB);
            execConsumer.accept();
        } finally {
            DynamicDataSourceContextHolder.poll();
        }
    }
    /**
     * 使用AOP的方式进行自动切换,通过获取aop的bean来防止方法调用方法而跳过aop
     * 例子:chooseDsUtil.getAopBean(this.getClass()).B(userPo);,使用B方法的@DS,进行数据源自动切换
     * @return
     */
    public <T> T getAopBean(Class<T> tClass) {
        return applicationContext.getBean(tClass);
    }
}
  1. 注意:不管是自动切换数据源还是手动切换数据源,切换执行完毕后都不会自动切换回来,比如:在更新逻辑中,先切换到读库进行数据获取,然后再数据处理,最后将处理后的数据更新到写库中,此时在写之前需要切换数据源到写库
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值