2016-04-15 6 views
2

私はRoutingDataSourceを使用して、アプリケーションの各テナントのデータソースを動的に作成しています。 8〜12時間後、アプリケーションアプリケーションはデータベースとの接続が失われ、jpaトランザクション例外が発生します。私は、次のプロパティがデータベース接続の検証と維持を担当しているので、application.propertiesに配置しました。Spring RoutingDataSource validationQueryがインジェクトされていません

​​3210

データソースBeanは、次のクラスで作成されます。上記のプロパティを各ターゲットデータソースに挿入するには?

... 

@Configuration 
public class RoutingDataSourceConfiguration { 

    public static final String DEFAULT_TENANT_NAME = "default_tenant"; 

    @Autowired 
    private RoutingDataSourceProperties routingProperties; 

    /** 
    * Defines the data source for the application 
    * 
    * @return 
    */ 
    @Bean 
    @ConfigurationProperties(prefix = "spring.datasource") 
    public DataSource dataSource() { 
     Map<Object, Object> dataSources = new HashMap<>(); 
     for (Map.Entry<String, DataSourceProperties> entry : routingProperties.getDataSources().entrySet()) { 
      DataSourceProperties dataSourceProperties = entry.getValue(); 
      dataSources.put(entry.getKey(), createDataSource(dataSourceProperties)); 
     } 
     RoutingDataSource dataSource = new RoutingDataSource(); 
     dataSource.setLenientFallback(false); 
     dataSource.setDefaultTargetDataSource(createDefaultDataSource()); 
     dataSource.setTargetDataSources(dataSources); 
     dataSource.afterPropertiesSet(); 
     return dataSource; 
    } 

    private DataSource createDataSource(DataSourceProperties dataSourceProperties) { 
     DataSourceBuilder dataSourceBuilder = new DataSourceBuilder(this.getClass().getClassLoader()); 
     dataSourceBuilder.driverClassName(dataSourceProperties.getDriverClassName()) 
       .url(dataSourceProperties.getUrl()) 
       .username(dataSourceProperties.getUsername()) 
       .password(dataSourceProperties.getPassword()); 

     if (dataSourceProperties.getType() != null) { 
      dataSourceBuilder.type(dataSourceProperties.getType()); 
     } 
     return dataSourceBuilder.build(); 
    } 

    private DataSource createDefaultDataSource() { 
     Map<String, DataSourceProperties> dataSources = routingProperties.getDataSources(); 
     if (!dataSources.containsKey(DEFAULT_TENANT_NAME)) { 
      throw new BeanCreationException(String.format(
        "No configuration for default tenant '%s' found", DEFAULT_TENANT_NAME)); 
     } 
     DataSourceProperties dataSourceProperties = dataSources.get(DEFAULT_TENANT_NAME); 
     return createDataSource(dataSourceProperties); 
    } 
} 

答えて

1

私は手動で(複数のデータソースと私の場合は)77.2あたりとして実用的データソースを作成するときに、検証クエリのクエリを設定する必要がありました。 Springboot 1.4+にはchangedのプロパティが設定されていますが、これは問題ありません。

これは少し醜いですが、それは私のために働いた。 Tomcat JDBCプーリングを使用していることを前提としています(spring-boot-starter-webを使用している場合のデフォルト)。

@Value("${spring.datasource.validation-query}") 
private String validationQuery; 

@Bean 
@ConfigurationProperties("spring.datasource") 
@Primary 
    public DataSourceProperties ftmDataSourceProperties() { 
    return new DataSourceProperties(); 
} 

@Bean 
@ConfigurationProperties("spring.datasource") 
@Primary 
public DataSource ftmDataSource() { 
    DataSource ds = ftmDataSourceProperties().initializeDataSourceBuilder().build(); 
    setTypeSpecificProperties(validationQuery,ds); 
    return ds; 
} 

private void setTypeSpecificProperties(String validationQuery, DataSource dataSource) { 
    org.apache.tomcat.jdbc.pool.DataSource typedDS = (org.apache.tomcat.jdbc.pool.DataSource) dataSource; 
    typedDS.setValidationQuery(validationQuery); 
    typedDS.setTestOnBorrow(true); 
    typedDS.setLogValidationErrors(true); 
} 
関連する問題