java - 如果 Hibernate 数据库连接失败,捕获 Grails 中的启动异常

标签 java spring hibernate grails grails-orm

我们正在使用 Grails 2.0.4、GORM 和 Hibernate 构建一个应用程序。当数据库不可用时,Grails 将不会初始化,并且启动失败。我们认为我们的池设置可以防止启动失败,但事实似乎并非如此。

如果单独的池设置无法解决此问题,是否可以在 resources.groovy 中捕获异常,如果数据库服务无法初始化,则暂时切换到基于文件的服务?像这样的事情...

resources.groovy

try{

   myDataService(PostgresDatabaseServiceImpl){}

}catch(Exception e){
   //if database connect failed, use local service instead
   myDataService(FileBasedServiceImpl){}
}

即使上述情况可行,也会产生新问题;一旦数据库可用,如何动态切换回来。我们尝试了上面的try/catch,但没有任何影响,启动问题仍然存在:

Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed

如果仅通过池设置就可以避免启动失败,那么当应用尝试使用错误的数据库连接时,我们当然可以在运行时管理 SQL 异常,但我们无法管理启动失败。

DataSource.groovy(池设置)

dataSource {
    pooled = true
    driverClassName = "org.postgresql.Driver"
    properties {
       maxActive = 20
       minEvictableIdleTimeMillis=1800000
       timeBetweenEvictionRunsMillis=1800000
       numTestsPerEvictionRun=3
       testOnBorrow=true
       testWhileIdle=true
       testOnReturn=true
       validationQuery="SELECT 1"
    }
}
hibernate {
    cache.use_second_level_cache = false
    cache.use_query_cache = false
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
} 

最佳答案

We attempted the above try/catch, but it had no impact, the startup issue persists:

看来您已经找到了是否可以在 resources.groovy 中为(可能)不可用的数据库注册 Spring bean 的问题的答案。

作为替代方案,您可以尝试在运行时为数据库注册 Spring bean。这种方法的优点是,即使注册 bean 失败,您也能够捕获错误并使用基于文件的服务。如何在运行时注册 DataSource bean 的示例是 show here .

要使用此方法,只需在 resources.groovy 中为基于文件的服务注册一个 Bean

myDataService(FileBasedServiceImpl)

然后当您需要访问数据源时:

class DataSourceService implements ApplicationContextAware {

  def myDataService
  ApplicationContext applicationContext

  private static PG_BEAN = 'postgres'

  def getDataSource() {

    try {
      getPostgresService()

    } catch (ex) {
      myDataService
    }
  }

  private getPostgresService() {
    def postgres

    if (applicationContext.containsBean(PG_BEAN)) {
      postgres = applicationContext.getBean(PG_BEAN)

    } else {
      // register a bean under the name 'postGres' and store a reference to it in postgres
      // https://stackoverflow.com/a/20634968/2648
    }            

    checkPostgres(postgres)
  }

  private checkPostres(postgresBean) {
    // check that the database is available, throw an exception if it's not, return 
    // postgresBean if it is
  }
}

关于java - 如果 Hibernate 数据库连接失败,捕获 Grails 中的启动异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20888590/

相关文章:

java - 正则表达式匹配 Unicode 和数字字符串

java - 如何设置JAssimp?

java - ResponseHandler 无法在 Android 的 SOAP Web 服务中工作?

spring - 如何使用原始 InputStream 实例化 FSDataInputStream?

sql - 有没有其他合乎逻辑或更健壮的方式

java - 如何知道 .jar Nexus Artifact 是从哪个分支发出的

java - 如何在创建 Spring 的 RestTemplate 时设置标题?

java - Spring :message 周围的空间

java - 将多个@Id 用于复合主键时出现 Eclipse 错误

java - 内存泄漏 org.jboss.modules.ModuleClassLoader。内存累积在 java.util.concurrent.ConcurrentHashMap 的一个实例中(在 Wildfly 上)