Skip to content

DDK DB Starter ​

一个服务连多个库时,按配置为每个库注册一组 DataSource、事务管理器和 JdbcTemplate,其中一组作为主数据源。不配置时完全不介入。

能做什么 ​

text
DdkDataSourceAutoConfiguration        before DataSourceAutoConfiguration
  DataSourcesRegistrar                按 ddk.datasource.sources 动态注册
    mainDataSource          @Primary
    mainTransactionManager  @Primary  JdbcTransactionManager
    mainJdbcTemplate        @Primary
    auditDataSource
    auditTransactionManager
    auditJdbcTemplate

Spring Boot 的 dataSource / transactionManager / jdbcTemplate  退让
  • 每个数据源一组 Bean,名字由配置的 key 决定:<name>DataSource、<name>TransactionManager、<name>JdbcTemplate。
  • 主数据源:由 primary 指定,只有一个数据源时自动成为主数据源。主数据源的三个 Bean 标记 @Primary,按类型注入、@Transactional 默认都落在它上面。
  • 连接池参数:pool.* 直接绑定到连接池实例,支持宽松写法,适用于任何连接池实现。
  • 启动期校验:多个数据源没指定 primary、primary 与任何数据源都不匹配、数据源缺 url,都在启动时失败并列出候选名。

引入方式 ​

xml
<dependency>
    <groupId>com.ddk</groupId>
    <artifactId>ddk-db-starter</artifactId>
    <version>${ddk.version}</version>
</dependency>

另需自行引入 JDBC 驱动。

yaml
ddk:
  datasource:
    primary: main
    sources:
      main:
        url: jdbc:mysql://localhost:3306/main
        username: app
        password: secret
        pool:
          maximum-pool-size: 20
          pool-name: main-pool
      audit:
        url: jdbc:mysql://localhost:3306/audit
        username: app
        password: secret

使用非主数据源时按名字指定:

java
@Transactional(transactionManager = "auditTransactionManager")
public void record(AuditEntry entry) {
    auditJdbcTemplate.update("INSERT INTO audit_log ...", ...);
}

配置项 ​

配置项类型说明
ddk.datasource.primaryString主数据源名字。配置了多个数据源时必填
ddk.datasource.sources.<name>.urlStringJDBC URL,必填
ddk.datasource.sources.<name>.username / passwordString账号密码
ddk.datasource.sources.<name>.driver-class-nameString通常可由 URL 推断
ddk.datasource.sources.<name>.typeClass连接池实现,默认按 classpath 选择(通常是 HikariCP)
ddk.datasource.sources.<name>.pool.*—连接池自身的属性,例如 HikariCP 的 maximum-pool-size、connection-timeout、leak-detection-threshold

装配条件与降级行为 ​

  • 自动配置类:com.ddk.db.starter.config.DdkDataSourceAutoConfiguration,before = DataSourceAutoConfiguration。
  • 条件:ddk.datasource.sources 非空时生效。没有配置时什么都不注册,spring.datasource.* 照常工作。
  • Bean 由 ImportBeanDefinitionRegistrar 在解析自动配置类时注册,保证早于 Boot 数据源配置的 @ConditionalOnMissingBean 判断。
  • 事务管理器是 JdbcTransactionManager,与 Spring Boot 一致:提交阶段的 SQLException 也会翻译成 DataAccessException。
  • Bean 定义登记具体的连接池类型(配置的 type,或按 classpath 探测到的实现),按 HikariDataSource 等实现类做类型查找无需先实例化。
  • 销毁方法按实际类型推断:连接池有 close(),SimpleDriverDataSource 之类没有也能正常启停。

不适用的场景 / 已知问题 ​

  1. @Transactional 默认使用主数据源的事务管理器。操作非主数据源必须写 @Transactional(transactionManager = "<name>TransactionManager"),否则事务作用在错误的连接上,这是多数据源方案最常见的线上事故。
  2. 没有运行时的数据源路由。没有 AbstractRoutingDataSource、没有 @DS 之类的注解,读写分离场景不适用。
  3. 只覆盖 JDBC 栈。与 DDK MyBatis Starter 组合时,MyBatis-Plus 只绑定主数据源;其他数据源要用 Mapper,需要自己配 SqlSessionFactory。
  4. 跨数据源没有原子性。每个数据源独立提交,需要分布式事务时配合 DDK Seata Starter。
  5. 密码以明文出现在配置里,没有集成外部密钥源,需要借助配置中心或环境变量注入。

文章以 CC BY-NC-SA 4.0 授权 · 代码片段以 MIT 授权