Spring boot 读写拆分/主-从/多数据库 [英] Spring boot Read write Split / Master - Slave / Multiple Databases

查看:32
本文介绍了Spring boot 读写拆分/主-从/多数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在关注此链接

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆