You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot2如何同时向两个MySQL数据库写入数据?application.yaml配置咨询

Spring Boot 2 双MySQL数据库(同结构)配置方案

1. application.yaml 配置

在配置文件中定义两个MySQL数据源,分别对应数据库a(主数据源,负责读写)和数据库b(仅写):

spring:
  datasource:
    # 主数据源:数据库a(读写)
    primary:
      url: jdbc:mysql://localhost:3306/a?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
      username: root
      password: your_db_password
      driver-class-name: com.mysql.cj.jdbc.Driver
    # 从数据源:数据库b(仅写)
    secondary:
      url: jdbc:mysql://localhost:3306/b?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
      username: root
      password: your_db_password
      driver-class-name: com.mysql.cj.jdbc.Driver

2. 数据源与持久化模板配置

创建配置类,初始化两个数据源对应的JdbcTemplate(若使用MyBatis,配置逻辑类似,需分别定义SqlSessionFactory和SqlSessionTemplate):

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    // 初始化主数据源(数据库a)
    @Primary
    @Bean(name = "primaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    // 初始化从数据源(数据库b)
    @Bean(name = "secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    // 主数据源对应的JdbcTemplate(默认使用,负责读+写)
    @Primary
    @Bean(name = "primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    // 从数据源对应的JdbcTemplate(仅用于写数据库b)
    @Bean(name = "secondaryJdbcTemplate")
    public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

3. 业务层实现双写+单读逻辑

在业务类中注入两个JdbcTemplate,读取操作仅用主数据源模板,写入操作同时调用两个模板执行相同SQL:

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

@Service
public class DataService {

    private final JdbcTemplate primaryJdbcTemplate;
    private final JdbcTemplate secondaryJdbcTemplate;

    // 构造注入
    public DataService(JdbcTemplate primaryJdbcTemplate,
                       @Qualifier("secondaryJdbcTemplate") JdbcTemplate secondaryJdbcTemplate) {
        this.primaryJdbcTemplate = primaryJdbcTemplate;
        this.secondaryJdbcTemplate = secondaryJdbcTemplate;
    }

    // 仅从数据库a读取数据
    public String readData(Long id) {
        String sql = "SELECT content FROM demo WHERE id = ?";
        return primaryJdbcTemplate.queryForObject(sql, String.class, id);
    }

    // 同时向数据库a和b写入数据
    public void writeData(Long id, String content) {
        String sql = "INSERT INTO demo(id, content) VALUES(?, ?) ON DUPLICATE KEY UPDATE content = ?";
        // 写入数据库a
        primaryJdbcTemplate.update(sql, id, content, content);
        // 写入数据库b
        secondaryJdbcTemplate.update(sql, id, content, content);
    }
}

注意事项

  • 事务一致性:上述双写逻辑未做分布式事务处理,若其中一个数据库写入失败会导致数据不一致。需强一致性场景可引入Seata等分布式事务框架。
  • MyBatis适配:若使用MyBatis,需为两个数据源分别配置SqlSessionFactory和SqlSessionTemplate,并通过@MapperScan指定不同数据源对应的Mapper路径。
  • 连接池优化:可在两个数据源配置下添加连接池参数(如hikari.maximum-pool-size)调整连接性能。

内容的提问来源于stack exchange,提问作者jie xu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 16:50:22