2016-04-15 4 views
2

Я использую RoutingDataSource для динамического создания источников данных для каждого арендатора нашего приложения. Через 8-12 часов приложение-приложение потеряло соединение с базой данных, и я получаю исключение транзакции jpa. Я обнаружил, что следующие свойства отвечают за проверку и поддержание связи с базой данных, поэтому я поместил их в свои application.properties.Spring RoutingDataSource validationQuery не вводится

spring.datasource.initialize=false 
spring.datasource.test-while-idle=true 
spring.datasource.test-on-borrow=true 
spring.datasource.validation-query=SELECT 1 

Источник данных 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 (по умолчанию при использовании весеннего загрузочного стартера):

@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); 
} 
Смежные вопросы