java.sql.SQLNonTransientConnectionException:连接关闭后不允许执行任何操作异常,仅在 Grails5 上使用默认数据源时

问题描述 投票:0回答:1

我有一个grails项目,刚刚从grails-3.1.6升级到grails-5.1.7。升级后,在使用默认数据源查询 MySQL 表时经常遇到通信链路失败的问题。

例外:

WARNING [http-nio-8088-exec-2] groovy.sql.Sql$AbstractQueryCommand.execute Failed to execute: SELECT id, loa, loa_id FROM crosswalk_table WHERE client_id=:clientId AND update_status=:updateStatus; because: No operations allowed after connection closed. java.sql.SQLNonTransientConnectionException: No operations allowed after connection closed.

这个问题是在部署环境中检测到的,当我关闭电脑大约十五分钟时,该问题也在本地环境中复制。 在我的 Intellij 或本地 tomcat 控制台中,它打印异常:

14-Dec-2023 00:05:44.096 SEVERE [Tomcat JDBC Pool Cleaner[1285282956:1702488174095]] org.apache.tomcat.jdbc.pool.ConnectionPool.reconnectIfExpired Failed to re-connect connection [org.apache.tomcat.jdbc.pool.ConnectionPool@7c24cbe8] that expired because of maxAge    com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

我的项目配置如下: 应用程序.yml

hibernate:
    cache:
        queries: false
        use_second_level_cache: true
        use_query_cache: false
        region.factory_class: 'org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory'

dataSources:
  dataSource:
      pooled: true
      jmxExport: true
      driverClassName: com.mysql.cj.jdbc.Driver
      dialect: "org.hibernate.dialect.MySQL5InnoDBDialect"
      properties:
          maxActive: 100
          maxIdle: 25
          minIdle: 5
          initialSize: 5
          maxWait: 10000
          removeAbandoned: true
          removeAbandonedTimeout: 400
          logAbandoned: true
          maxAge: 60000
          minEvictableIdleTimeMillis: 5000
          timeBetweenEvictionRunsMillis: 15000
          numTestsPerEvictionRun: 3
          testOnBorrow: true
          testWhileIdle: true
          testOnReturn: true
          validationQuery: "SELECT 1"
          validationQueryTimeout: 3
          validationInterval: 15000

  pa:
      pooled: true
      jmxExport: true
      driverClassName: com.mysql.cj.jdbc.Driver
      dialect: "org.hibernate.dialect.MySQL5InnoDBDialect"
      properties:
          maxActive: 100
          maxIdle: 25
          minIdle: 5
          initialSize: 5
          maxWait: 10000
          removeAbandoned: true
          removeAbandonedTimeout: 400
          logAbandoned: true
          maxAge: 60000
          minEvictableIdleTimeMillis: 5000
          timeBetweenEvictionRunsMillis: 15000
          numTestsPerEvictionRun: 3
          testOnBorrow: true
          testWhileIdle: true
          testOnReturn: true
          validationQuery: "SELECT 1"

我已将另一个 yml 文件中的主机网址、用户名和密码外部化为:

dataSources:
  dataSource:
    dbCreate: none
    url: jdbc:mysql://localhost:3306/everest_dev?zeroDateTimeBehavior=convertToNull&useSSL=false
    username: root
    password: root
  pa:
    dbCreate: none
    url: jdbc:mysql://localhost:3306/solu_dev?zeroDateTimeBehavior=convertToNull&useSSL=false
    username: root
    password: root

代码示例:

@Slf4j
class LoaService {
      def dataSource
  
      def getLoaEditDataD(Map params) {
        String dwClientId = params.get("dwClientId", String.class)
        Sql sqlDAS
        try {
            sqlDAS = Sql.newInstance(dataSource)
            def sqlQuery = "SELECT id, loa, loa_id FROM loa_editor_crosswalk_table " +
                    "WHERE client_id=:clientId AND update_status=:updateStatus;"
            def sqlParams = [clientId: dwClientId, updateStatus: 'Completed', isDeleted: false]
            def result = sqlDAS.rows(sqlQuery, sqlParams)
            return result
        } catch (Exception exc) {
            exc.printStackTrace()
        } finally {
            if (sqlDAS != null) sqlDAS.close()
        }
    }

仅在使用默认数据源时才会重现此通信链路失败的问题;如果使用dataSource_pa,问题不会重现。

其他项目配置:

  • 摇篮:gradle-7.2
  • JDK:1.8.0
  • Tomcat:apache9.0.84/apache8.5.85
  • MySQL:8.0.32
  • MySQL 驱动程序:实现 “mysql:mysql-connector-java:8.0.19”
  • Hibernate:实现 “org.grails.plugins:hibernate5”和 “org.hibernate:hibernate-core:5.6.5.Final”

使用自定义的dataSource_pa解决了通信链路故障,使用GORM方法可以避免此类故障。 默认数据源是唯一的问题。因此,我必须查明这次失败的原因可能是什么。

java mysql tomcat grails mysql-connector
1个回答
0
投票

我也在找同样的问题...

© www.soinside.com 2019 - 2024. All rights reserved.