SpringBoot 报 No operations allowed after connection closed 异常解决办法

时间:2022-07-26
本文章向大家介绍SpringBoot 报 No operations allowed after connection closed 异常解决办法,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.1 异常原因

  MySQL 5.0 以后针对超长时间数据库连接做了一个处理,即一个数据库连接在无任何操作情况下过了 8 个小时后(MySQL 服务器默认的超时时间是 8 小时),MySQL 会自动把这个连接关闭。在数据库连接池中的 connections 如果空闲超过 8 小时,MySQL 将其断开,而数据库连接池并不知道该 connection 已经失效,这个时候你请求数据库链接,连接池会将失效的 connection 给你,so~,SpringBoot 温柔的告诉你 No operations allowed after connection closed。SpringBoot 2.0 以上版本,mysql-connector-java 默认使用的是 8.0 以上版本。

1.2 解决办法

1.2.1 hikari 数据库连接池配置

☞ 概述   SpringBoot 2.0 开始推 HikariCP,将默认的数据库连接池从 tomcat jdbc pool 改为了 hikari,HikariCP 在性能和并发方面确实表现不俗(号称最快的连接池)。使用 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa,会自动添加对 HikariCP 的依赖,也就是说此时使用 HikariCP。通过在 application.properties 或 application.yml 中配置 spring.datasource.type 指定数据库连接池,强制使用其它的连接池技术。

☞ 示例

spring:
  datasource:
    hikari:
      # 连接池最大连接数,默认是 10
      maximum-pool-size: 60
      # 链接超时时间,默认 30000(30 秒)
      connection-timeout: 60000
      # 空闲连接存活最大时间,默认 600000(10 分钟)
      idle-timeout: 60000
      # 连接将被测试活动的最大时间量
      validation-timeout: 3000
      # 此属性控制池中连接的最长生命周期,值 0 表示无限生命周期,默认 1800000(30 分钟)
      max-lifetime: 60000
      # 连接到数据库时等待的最长时间(秒)
      login-timeout: 5
      # 池中维护的最小空闲连接数
      minimum-idle: 10

☞ 配置说明

name

描述

默认值

autoCommit

自动提交从池中返回的连接

true

connectionTimeout

等待来自池的连接的最大毫秒数

30000 ms

idleTimeout

连接允许在池中闲置的最长时间

600000 ms

maxLifetime

池中连接最长生命周期

1800000 ms

connectionTestQuery

如果您的驱动程序支持 JDBC 4,我们强烈建议您不要设置此属性

null

minimumIdle

池中维护的最小空闲连接数

-1

maximumPoolSize

池中最大连接数,包括闲置和使用中的连接

-1

metricRegistry

该属性允许您指定一个 Codahale / Dropwizard MetricRegistry 的实例,供池使用以记录各种指标

null

healthCheckRegistry

该属性允许您指定池使用的 Codahale / Dropwizard HealthCheckRegistry 的实例来报告当前健康信息

null

poolName

连接池的用户定义名称,主要出现在日志记录和 JMX 管理控制台中以识别池和池配置

null

initializationFailTimeout

如果池无法成功初始化连接,则此属性控制池是否将 fail

fast

isolateInternalQueries

是否在其自己的事务中隔离内部池查询,例如连接活动测试

false

allowPoolSuspension

控制池是否可以通过 JMX 暂停和恢复

false

readOnly

从池中获取的连接是否默认处于只读模式

false

registerMbeans

是否注册 JMX 管理 Bean(MBeans)

false

catalog

为支持 catalog 概念的数据库设置默认 catalog

driver default

connectionInitSql

该属性设置一个 SQL 语句,在将每个新连接创建后,将其添加到池中之前执行该语句。

null

driverClassName

HikariCP 将尝试通过仅基于 jdbcUrl的DriverManager 解析驱动程序,但对于一些较旧的驱动程序,还必须指定 driverClassName

null

transactionIsolation

控制从池返回的连接的默认事务隔离级别

null

validationTimeout

连接将被测试活动的最大时间量

5000 ms

leakDetectionThreshold

记录消息之前连接可能离开池的时间量,表示可能的连接泄漏

0

dataSource

这个属性允许你直接设置数据源的实例被池包装,而不是让 HikariCP 通过反射来构造它

null

schema

该属性为支持模式概念的数据库设置默认模式

driver default

threadFactory

此属性允许您设置将用于创建池使用的所有线程的 java.util.concurrent.ThreadFactory 的实例。

null

scheduledExecutor

此属性允许您设置将用于各种内部计划任务的 java.util.concurrent.ScheduledExecutorService 实例

null

1.2.2 Druid 数据库连接池配置

spring:
  datasource:
  druid:
      # 初始化时建立物理连接的个数。初始化发生在显示调用 init 方法,或者第一次 getConnection 时
      initial-size: 10
      # 连接池中最小连接数量
      min-idle: 10
      # 连接池用最大连接数量
      maxActive: 20
      # 获取连接时最大等待时间,单位毫秒。
      maxWait: 60000
      # 关闭空闲连接的检测时间间隔 Destroy 线程会检测连接的间隔时间,如果连接空闲时间大于等于则关闭物理连接。
      timeBetweenEvictionRunsMillis: 60000
      # 连接的最小生存时间,连接保持空闲而不被驱逐的最小时间
      minEvictableIdleTimeMillis: 300000
      # 验证数据库服务可用性的 sql,用来检测连接是否有效的 sql。oracle 应该写成 SELECT 1 FROM DUAL 
      validationQuery: SELECT 1 FROM DUAL
      # 申请连接时检测空闲时间,根据空闲时间再检测连接是否有效,建议配置为 true,不影响性能,并且保证安全性。
      testWhileIdle: true
      # 申请连接时直接检测连接是否有效,申请连接时执行 validationQuery 检测连接是否有效,开启会降低性能。
      testOnBorrow: false
      # 归还连接时检测连接是否有效,归还连接时执行 validationQuery 检测连接是否有效,开启会降低性能。
      testOnReturn: false
      # 开启 PSCache
      poolPreparedStatements: true
      # 设置 PSCache 的值
      maxPoolPreparedStatementPerConnectionSize: 20
      # 连接出错后再尝试连接三次
      connectionErrorRetryAttempts: 3
      # 数据库服务宕机自动重连机制
      breakAfterAcquireFailure: true
      # 连接出错后重试时间间隔
      timeBetweenConnectErrorMillis: 300000
      # 异步初始化策略
      asyncInit: true
      # 是否自动回收超时连接
      remove-abandoned: true
      # 超时时间(秒)
      remove-abandoned-timeout: 1800
      # 事务超时时间
      transaction-query-timeout: 6000
      # 配置监控统计拦截的 filters,去掉后监控界面 sql 无法统计,wall 用于防火墙
      filters: stat,wall,log4j2
      # 通过 connection-properties 属性打开 mergeSql 功能;慢 SQL 记录
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # 配置 DruidStatFilter
      web-stat-filter:
        enabled: true
        url-pattern: "/*"
        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
      # 配置 DruidStatViewServlet
      stat-view-servlet:
        url-pattern: /druid/*
        # IP 白名单,没有配置或者为空,则允许所有访问
        allow: 127.0.0.1
        # IP 黑名单,若白名单也存在,则优先使用
        deny: 192.168.31.253
        # 禁用 HTML 中 Reset All 按钮
        reset-enable: false
        # 登录用户名 / 密码
        login-username: root
        login-password: 123