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
相关产品推荐
相关产品推荐

