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

猜你喜欢

转载自blog.csdn.net/Demo_Null/article/details/107905262