多数据源下配置shardingjdbc,导致主数据源失效的场景

多数据源下配置shardingjdbc,导致主数据源失效的场景

  • 配置主数据源和通过shardingjdbc进行分表配置
    • 先看主要配置信息
    • 出现问题的场景
    • 问题修改

配置主数据源和通过shardingjdbc进行分表配置

本人在此次分表过程中遇到了这样的事情,主业务都在主数据源上,分表的数据源和主数据源不是同一个数据库。一切配置好后,分表插入数据也没有问题,后面测试主业务场景时,发现主数据源失效,楞是花了我大半天时间才找到原因,在这里分享下,希望你们不会遇到。

先看主要配置信息

  1. 引入需要的依赖
		<dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.0.0-RC1</version>
        </dependency>

        <!--依赖dynamic-datasource-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.2.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-core-common</artifactId>
            <version>4.0.0-RC1</version>
        </dependency>
  1. 进行数据源配置
spring:
  application:
    # 应用名称
    name: weygy
  profiles:
    # 环境配置
    active: dev
  main:
    allow-bean-definition-overriding: true
  datasource:
    dynamic:
      primary: master
      datasource:
        master:
          username: root
          password: root
          url: jdbc:mysql://127.0.0.1:3306/center?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
          driver-class-name: com.mysql.cj.jdbc.Driver
  shardingsphere:
    datasource:
      names: logging
      logging:
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://127.0.0.1:3306/report?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowMultiQueries=true
        username: root
        password: root
        type: com.zaxxer.hikari.HikariDataSource
    sharding:
      #指定data表的数据分布情况。
      #data_$->{1..3}:logging.data_1;logging.data_2;
      tables:
        data:
          actual-data-nodes: logging.data_$->{1..3}
          #指定表的主键生成策略SNOWFLAKE
          key-generator:
            column: data_id
            type: SNOWFLAKE
          #指定表的分片策略,包括分片键和分片算法
          table-strategy:
            inline:
              sharding-column: data_id
              algorithm-expression: data_$->{data_id % 3 + 1}

这里分了三张表

  1. 添加Dynamic-datasource的动态数据源配置类
package cn.logging.config;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Map;

/**
 * @ClassName: DataSourceConfiguration
 * @Description: Dynamic-datasource的动态数据源配置类
 * @author: Sir
 * @date: 2023/4/18 17:55
 * @version: 1.0
 **/
@Configuration
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class, SpringBootConfiguration.class})
public class DataSourceConfiguration {

    @Resource
    private DynamicDataSourceProperties properties;

    /**
     * shardingjdbc有四种数据源,需要根据业务注入不同的数据源
     *
     * 

1. 未使用分片, 脱敏的名称(默认): shardingDataSource; *

2. 主从数据源: masterSlaveDataSource; *

3. 脱敏数据源:encryptDataSource; *

4. 影子数据源:shadowDataSource *

5. 分片使用数据源:shardingSphereDataSource * */ @Lazy @Resource private DataSource shardingSphereDataSource; @Bean public DynamicDataSourceProvider dynamicDataSourceProvider() { Map<String, DataSourceProperty> datasourceMap = properties.getDatasource(); return new AbstractDataSourceProvider() { @Override public Map<String, DataSource> loadDataSources() { Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap); dataSourceMap.put("sharding", shardingSphereDataSource); //打开下面的代码可以把 shardingjdbc 管理的数据源也交给动态数据源管理 (根据自己需要选择开启) //dataSourceMap.putAll(((MasterSlaveDataSource) masterSlaveDataSource).getDataSourceMap()); return dataSourceMap; } }; } /** * 将动态数据源设置为首选的 * 当spring存在多个数据源时, 自动注入的是首选的对象 * 设置为主要的数据源之后,就可以支持shardingjdbc原生的配置方式了 */ @Primary @Bean public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) { DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource(); dataSource.setPrimary(properties.getPrimary()); dataSource.setStrict(properties.getStrict()); dataSource.setStrategy(properties.getStrategy()); dataSource.setProvider(dynamicDataSourceProvider); dataSource.setP6spy(properties.getP6spy()); dataSource.setSeata(properties.getSeata()); return dataSource; } }

  1. 场景测试

分表的插入数据场景,需要加上:@DS(“sharding”)

    @Override
    @DS("sharding")
    public ResultDataVo reportEvent() {
        ReportData data = new ReportData();
        loggingService.reportEvent(data);
        return getVo(dto);
    }

主业务插入数据场景:不用加注解,默认进入

@Service
public class loggingEventServiceImpl implements loggingEventService {

    @Autowired
    private loggingEventMapper loggingEventMapper;

    @Override
    public void insertloggingEvent(loggingEventPo loggingEventPo) {
        loggingEventMapper.insertloggingEvent(loggingEventPo);
    }
}

出现问题的场景

### Cause: java.sql.SQLSyntaxErrorException: Table 'logging_report.event' doesn't exist

这里出现该问题的主要原因可以在:Dynamic-datasource的动态数据源配置类中查看出来,这里只进入了第一个断点,没有进入第二个断点
多数据源下配置shardingjdbc,导致主数据源失效的场景_第1张图片

问题修改

修改方法将依赖版本增加到4.1
多数据源下配置shardingjdbc,导致主数据源失效的场景_第2张图片

此时进入第二个断点,加载数据源。主数据源使用不需要加注解,默认主数据源,分表的数据源使用需要加注解:@DS(“sharding”)
多数据源下配置shardingjdbc,导致主数据源失效的场景_第3张图片

你可能感兴趣的:(mysql,数据库,java)