Grails 在失败时自动重新打开连接

Grails automatically reopen connection on fail

我有一个 Grails 应用程序通过域 类 与 ingres 数据库通信。当数据库崩溃或我在应用程序 运行 时重新启动它时,我得到一个异常:

| Error Caused by: java.sql.SQLTransactionRollbackException: Connection failed.

尽管数据库已从 restart/crash.

再次访问数据库,但每次访问数据库时都会永远出现此异常

如何强制 Grails/Hibernate 重新创建连接或将其设置为自动重新创建。

这是我的配置:

dataSource {
    dbCreate = 'validate'
    url = "jdbc:ingres://xxx.xxx.xxx.xxx:II7/test"
    driverClassName = "com.ingres.jdbc.IngresDriver"
    username = "ingres"
    password = "ingres"
    jmxEnabled = true
    initialSize = 5
    maxActive = 50
    minIdle = 5
    maxIdle = 25
    maxWait = 10000
    maxAge = 10 * 60000
    timeBetweenEvictionRunsMillis = 5000
    minEvictableIdleTimeMillis = 60000
    validationQuery = "SELECT 1"
    validationQueryTimeout = 3
    validationInterval = 15000
    testOnBorrow = true
    testWhileIdle = true
    testOnReturn = true
    jdbcInterceptors = "ConnectionState"
    defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
}

java.sql.SQLTransactionRollbackException表示最后一条可能导致数据库崩溃的语句由于死锁或其他事务序列化失败而被数据库自动回滚。

重启并不能解决这个问题,可能是驱动程序的特定问题。似乎 SQLState 没有被重置(可能仍然包含值“40”,或者供应商特定的值可能是什么)。

也许主要的重点应该是在应用程序级别查明数据库崩溃的原因。在应用程序 运行 时重新启动数据库服务器无论如何都是不好的做法。

检查自动重新连接参数:

dataSource {
    url = "jdbc:mysql://localhost/databaseName?useUnicode=yes&characterEncoding=UTF-8&autoReconnect=true"
        }

另一个可能有用的属性:

dataSource {
    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    username = "secret"
    password = "santa"

   properties {
      maxActive = 50
      maxIdle = 25
      minIdle = 1
      initialSize = 1

      numTestsPerEvictionRun = 3
      maxWait = 10000

      testOnBorrow = true
      testWhileIdle = true
      testOnReturn = true

      validationQuery = "select now()"

      minEvictableIdleTimeMillis = 1000 * 60 * 5
      timeBetweenEvictionRunsMillis = 1000 * 60 * 5
   }
}

经过数小时的搜索和丢失关键信息后,问题很容易解决。

在我问题的初始配置中,没有 properties {..} 围绕数据源设置的组。天才的 Grails 配置管理没有警告我需要它。添加它,一切正常,GORM 可以从丢失的连接中恢复。