Spring boot 读写拆分/主-从/多数据库 [英] Spring boot Read write Split / Master - Slave / Multiple Databases
问题描述
我正在关注此链接
https://github.com/kwon37xi/replication-datasource
我已经实现了代码但是我的两个服务功能都在使用同一个数据库(一个被标记为主要的)
I have implemented the code But STILL Both my service functions are using the same Database(one which is marked primary)
服务类
public class TableService{
@Autowired
private Table1Repo t1Repo;
@Transactional(readOnly = false)
public void saveTable1(Table1 t,int a, Table1 t2){
try{
t1Repo.save(t2);
}
catch(Exception e){
System.out.println("Inside");
}
}
@Transactional(readOnly = true)
public Table1 getTable(int id){
return t1Repo.findOne(id);
}
}
然后添加了两个类(来自链接)
Then Added two Class(from the link)
ReplicationRoutingDataSource
ReplicationRoutingDataSource
public class ReplicationRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
String dataSourceType = TransactionSynchronizationManager.isCurrentTransactionReadOnly() ? "read" : "write";
return dataSourceType;
}
}
WithRoutingDataSourceConfig
WithRoutingDataSourceConfig
@Configuration
public class WithRoutingDataSourceConfig {
/*@Bean(destroyMethod = "shutdown")*/
@Bean
@Primary
@ConfigurationProperties(prefix="datasource.primary")
public DataSource writeDataSource() {
/* EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
.setName("routingWriteDb")
.setType(EmbeddedDatabaseType.H2)
.setScriptEncoding("UTF-8")
.addScript("classpath:/writedb.sql");
return builder.build();*/
return DataSourceBuilder.create().build();
}
/* @Bean(destroyMethod = "shutdown")*/
@Bean
@ConfigurationProperties(prefix="datasource.secondary")
public DataSource readDataSource() {
/*EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
.setName("routingReadDb")
.setType(EmbeddedDatabaseType.H2)
.setScriptEncoding("UTF-8")
.addScript("classpath:/readdb.sql");
return builder.build();*/
return DataSourceBuilder.create().build();
}
/**
* {@link org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource}는
* {@link org.springframework.beans.factory.InitializingBean}을 구현하므로,
* 명시적으로 afterPropertiesSet()메소드를 호출하거나
* 별도 @Bean으로 만들어 Spring Life Cycle을 타도록 해야 한다.
*/
@Bean
public DataSource routingDataSource(@Qualifier("writeDataSource") DataSource writeDataSource, @Qualifier("readDataSource") DataSource readDataSource) {
ReplicationRoutingDataSource routingDataSource = new ReplicationRoutingDataSource();
Map<Object, Object> dataSourceMap = new HashMap<Object, Object>();
dataSourceMap.put("write", writeDataSource);
dataSourceMap.put("read", readDataSource);
routingDataSource.setTargetDataSources(dataSourceMap);
routingDataSource.setDefaultTargetDataSource(writeDataSource);
return routingDataSource;
}
/**
* {@link org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy}로 감싸서
* 트랜잭션 동기화가 이루어진 뒤에 실제 커넥션을 확보하도록 해준다.
*
* @param routingDataSource
* @return
*/
@Bean
public DataSource dataSource(@Qualifier("routingDataSource") DataSource routingDataSource) {
return new LazyConnectionDataSourceProxy(routingDataSource);
}
}
application.prop 文件
server.port=8089
spring.jpa.show-sql = true
spring.jpa.properties.hibernate.show_sql=true
# Primary DataSource configuration
datasource.primary.url=jdbc:mysql://127.0.0.1:3306/jpa
datasource.primary.username=root
datasource.primary.password=root
# Any of the other Spring supported properties below...
# Secondary DataSource configuration
datasource.secondary.url=jdbc:mysql://127.0.0.1:3306/jpa2
datasource.secondary.username=root
datasource.secondary.password=root
存储库
public interface Table1Repo extends JpaRepository<Table1, Integer>{}
问题是我的两个服务功能都使用主数据库.我错过了什么.我只有这些课.休息我有一个控制器
Issue is my both service functions are using the primary Database. What am I missing. I only have these class. Rest I have one Controller
已编辑我通过添加这个类使代码工作
Edited I have made by code work by adding this class
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.example")
public class ReplicationDataSourceApplicationConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("dataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
emfb.setDataSource(dataSource);
emfb.setPackagesToScan("com.example");
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
emfb.setJpaVendorAdapter(jpaVendorAdapter);
return emfb;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslationPostProcessor() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
推荐答案
我是您引用的链接的作者.
I'm the writer of the link you refered.
您在 Table1Repo 中使用哪个数据源?
Which data source do you use with Table1Repo?
您必须向 JDBC 调用注入特定的 beandataSource".
You have to inject the specific bean "dataSource" to you JDBC call.
我猜 @Primary
writeDataSource" 被注入到您的存储库中.
I guess @Primary
"writeDataSource" is injected to your Repository.
尝试将 @Primary
更改为dataSource"或找到将dataSource"注入存储库的方法.
Try to change @Primary
to "dataSource" or find a way to inject "dataSource" to your repository.
这篇关于Spring boot 读写拆分/主-从/多数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!