关于java:MybatisPlus多数据源使用多线程时失效的问题

Mybatis-Plus多数据源应用也是极为不便,应用@DS注解即可。然而不论加在类上还是加在实现接口的办法上,均不能正确的找到对应的数据库,所有的线程都抓着主数据库不放。

几经周折,屡次试验,最终将多数据源的注解申明在了Callable实现类的call办法上,并且须要用编码的形式,设置以后线程数据源名称,并在以后线程执行完结后,再将其革除掉。

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;

    @Override
    public Future<Map<String, Object>> getTableOverview(CountDownLatch latch) {
        return executor.submit(new Callable<Map<String, Object>>() {
            @DS("slave")
            @Override
            public Map<String, Object> call() throws Exception {
                // 设置以后线程数据源
                DynamicDataSourceContextHolder.push("slave");
                Map<String, Object> result;
                try {
                    // 查询数据库办法
                    result = getTableData();
                } finally {
                    latch.countDown();
                    // 强制清空本地线程,避免内存透露,手动调用push可调用此办法确保革除
                    DynamicDataSourceContextHolder.clear();
                }
                return result;
            }
        });
    }
MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上增加了许实用的功能,其中就包括动态数据源的支持。 MyBatis-Plus 的动态数据源实现,主要是通过使用 Spring 提供的 AbstractRoutingDataSource 类和 ThreadLocal 来实现的。具体步骤如下: 1. 首先需要在 Spring 的配置文件中配置个数据源,并且将这些数据源注入到 AbstractRoutingDataSource 类中。 2. 然后通过自定义一个继承自 AbstractRoutingDataSource 的数据源路由类,重写它的 determineCurrentLookupKey() 方法,该方法根据当前线程的 ThreadLocal 中保存的数据源标识来选择对应的数据源。 3. 最后,将自定义的数据源路由类注入到 Spring 的事务管理器中即可。 示例配置: ```xml <bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource"> <!-- 数据源配置 --> </bean> <bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource"> <!-- 数据源配置 --> </bean> <bean id="dataSource" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <property name="mapperLocations" value="classpath*:mapper/*.xml"/> <property name="dataSource" ref="dataSourceRouter"/> </bean> <bean id="dataSourceRouter" class="com.example.DataSourceRouter"> <property name="targetDataSources"> <map> <entry key="dataSource1" value-ref="dataSource1"/> <entry key="dataSource2" value-ref="dataSource2"/> </map> </property> <property name="defaultTargetDataSource" ref="dataSource1"/> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSourceRouter"/> </bean> ``` 自定义数据源路由类: ```java public class DataSourceRouter extends AbstractRoutingDataSource { private static final ThreadLocal<String> dataSourceHolder = new ThreadLocal<>(); public static void setDataSource(String dataSource) { dataSourceHolder.set(dataSource); } @Override protected Object determineCurrentLookupKey() { return dataSourceHolder.get(); } } ``` 在业务代码中,可以通过调用 DataSourceRouter.setDataSource() 方法来设置当前线程要使用的数据源标识。 ```java // 使用 dataSource1 数据源 DataSourceRouter.setDataSource("dataSource1"); // 使用 dataSource2 数据源 DataSourceRouter.setDataSource("dataSource2"); ``` 这样就可以实现动态地切换数据源了。注意,数据源切换要在事务开启之前进行,否则事务会失效
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值