Spring:允许丢失数据库连接

标签 spring spring-boot hikaricp

我有一个连接到多个数据库(Oracle 和 SQLServer)的项目,其中一些在启动应用程序时并不总是强制性的或不可用的 - 特别是在开发环境中。

我正在寻找一种允许应用程序在没有数据库连接的情况下启动的方法。我们只需要在执行特定任务时连接到这些数据库,这些任务使用需要特定网络访问权限的登台数据库,但在开发人员中并不总是可用。

在这里,使用我们的 Oracle 连接(在特定网络下的连接):

我们有一个允许应用程序启动的配置,但由于错误的 HikariDataSource 转换而在运行测试时抛出错误:

@Configuration
@EnableJpaRepositories(
        basePackages = "com.bar.foo.repository.oracle",
        entityManagerFactoryRef = "oracleEntityManager",
        transactionManagerRef = "oracleTransactionManager"
)
public class OracleConfiguration {
private final Logger            log = LoggerFactory.getLogger(this.getClass());

@Inject
private Environment             environment;

@Value("${spring.datasource.oracle.ddl-auto:none}")
private String hibernateddlAuto;

@Value("${spring.datasource.oracle.dialect:org.hibernate.dialect.Oracle10gDialect}")
private String hibernateDialect;

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

@Bean
@Primary
@ConfigurationProperties("spring.datasource.hikari")
public DataSource oracleDataSource() {
    HikariDataSource ds = (HikariDataSource) oracleDataSourceProperties().initializeDataSourceBuilder().build();
    ds.setPoolName(environment.getProperty("spring.datasource.oracle.poolName"));
    return ds;
}


@Bean
@Primary
public LocalContainerEntityManagerFactoryBean oracleEntityManager() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setPackagesToScan("com.bar.foo.domain.oracle");
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    HashMap<String, Object> properties = new HashMap<>();
    properties.put("hibernate.ddl-auto", hibernateddlAuto);
    properties.put("hibernate.dialect", hibernateDialect);
    em.setJpaPropertyMap(properties);
    em.setDataSource(oracleDataSource());
    return em;
}

@Primary
@Bean
public PlatformTransactionManager oracleTransactionManager() {

    JpaTransactionManager transactionManager


     = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(
            oracleEntityManager().getObject());
    return transactionManager;
}
}

我移动了这个配置来扩展 HikariConfig 如下:

@Configuration
@EnableJpaRepositories(
    basePackages = "com.bar.foo.repository.oracle",
    entityManagerFactoryRef = "oracleEntityManager",
    transactionManagerRef = "oracleTransactionManager"
)
@ConfigurationProperties("spring.datasource.oracle")
public class OracleConfiguration extends HikariConfig{


    @Bean
    @Primary
    public DataSource oracleDataSource() {
      return new HikariDataSource(this);
    }

    @Bean
    @Primary
public LocalContainerEntityManagerFactoryBean oracleEntityManager() {
  LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
  em.setPackagesToScan("com.bar.foo.domain.oracle");
  HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
  em.setJpaVendorAdapter(vendorAdapter);
  HashMap<String, Object> properties = new HashMap<>();
      properties.put("hibernate.ddl-auto", hibernateddlAuto);
      properties.put("hibernate.dialect", hibernateDialect);
  em.setJpaPropertyMap(properties);
  em.setDataSource(oracleDataSource());
  return em;
}

@Bean
@Primary
public PlatformTransactionManager oracleTransactionManager() {

  JpaTransactionManager transactionManager
    = new JpaTransactionManager();
  transactionManager.setEntityManagerFactory(
    oracleEntityManager().getObject());
  return transactionManager;
}

如果 Oracle 数据库不可用,它不会启动。
使用嵌入式数据库不适合我们的用例,因为我们并不总是需要这种连接,而当我们需要时,我们需要从生产中复制特定数据。 在多个微服务/应用程序上拆分它也是不行的,因为这将是一个巨大的重构,并且并不真正适合我们的用例(我们将来自多个来源的数据聚合到一个最终数据中)。

有没有一种简单的方法可以做到这一点?

最佳答案

HikariCP 提供了一些真正的 nice configuration properties这可能适合您的需要。具体来说(该列表中的第一个)initializationFailTimeout:

This property controls whether the pool will "fail fast" if the pool cannot be seeded with an initial connection successfully...

A value less than zero will bypass any initial connection attempt, and the pool will start immediately while trying to obtain connections in the background. Consequently, later efforts to obtain a connection may fail.

如果你想以这种方式解决你的问题,即通过隐藏任何初始化失败(通过设置一个负的 initializationFailTimeout 值),那么你只需要确保你有正确的逻辑当您从池中获取连接时,数据库无法访问/关闭的情况。

关于Spring:允许丢失数据库连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50531636/

相关文章:

Java-设置成员变量后,如何设置其他成员

java - 在大型事务中安全清除 Hibernate session

spring-boot - Spring Boot : property spring. jpa.show-sql 不适用于数据存储

apache-tomee - 如何通过 Tomee.xml 配置 HikariCP?

java - 没有从字符串值 ('' 反序列化的字符串参数构造函数/工厂方法)

java - SpringJUnit4ClassRunner 不会在 JUnit 测试用例结束时关闭 Application Context

spring - 服务和 Controller 层异常处理设计模式

java - 如何将 session 属性传递给 ThymeLeaf 表单字段以保存到数据库中

java - Spring boot + hikari - dataSource 或 dataSourceClassName 或 jdbcUrl 是必需的问题

Hibernate + HikariCP + EHCache session 创建失败