mybatis多数据源出现No operations allowed after connection closed.?

之前单数据源的时候没有出现过这样的问题,也没有配置test-while-idle=true这一类的参数。配置如下
image.png
image.png
切换成多数据源之后
image.png
就开始出现No operations allowed after connection closed.
网上搜索是要加上mybatis的相关的配置
image.png
请问是加上这些就能好使吗? 那为什么单数据源的时候不用加呢?

阅读 411
avatarAI BotBETA

是的,添加testWhileIdle等配置可以解决这个问题。核心原因是多数据源场景下的连接池生命周期管理差异:

  1. 单数据源默认行为:
  2. 部分连接池(如HikariCP)默认会启用keepalive机制(30秒探测)
  3. Spring Boot自动配置会隐式设置合理的validationQuery
  4. 多数据源配置时:
  5. 每个数据源的配置需要显式声明所有参数
  6. 连接池默认参数会被重置(比如Druid默认testWhileIdle=false)
  7. 不同数据源之间的连接不能共享心跳机制

建议配置示例:

# 数据源1
spring.datasource.druid.one.test-while-idle=true
spring.datasource.druid.one.validation-query=SELECT 1
spring.datasource.druid.one.time-between-eviction-runs-millis=60000

# 数据源2 
spring.datasource.druid.two.test-while-idle=true
spring.datasource.druid.two.validation-query=SELECT 1
spring.datasource.druid.two.time-between-eviction-runs-millis=60000

注意需要同时配置三个参数才会生效:

  • testWhileIdle:开启空闲检测
  • validationQuery:数据库ping语句
  • timeBetweenEvictionRunsMillis:检测间隔

该现象的本质是:当使用多数据源时,连接池的空闲连接被数据库主动断开(如MySQL的wait_timeout),而连接池未能及时检测到连接失效。单数据源场景下Spring Boot的自动配置会帮我们设置合理的默认值,但多数据源时需要手动补全这些配置。

1 个回答

是的,添加图片中展示的配置通常能解决这个问题,特别是这些关键参数:

spring.datasource.primary.test-while-idle=true
spring.datasource.primary.time-between-eviction-runs-millis=18000

对每个数据源都需要类似配置:

# 主数据源
spring.datasource.primary.test-while-idle=true
spring.datasource.primary.validation-query=SELECT 1

# 测试数据源
spring.datasource.test1.test-while-idle=true
spring.datasource.test1.validation-query=SELECT 1

配置说明

  1. test-while-idle=true

    • 关键配置,让连接池定期检查空闲连接是否有效
    • 避免使用已关闭的连接
  2. validation-query

    • 用于测试连接是否有效的SQL
    • 通常使用轻量级查询如"SELECT 1"
  3. time-between-eviction-runs-millis

    • 空闲连接检查的时间间隔
    • 18000毫秒(18秒)是个合理值
  4. min-idlemax-idle

    • 控制连接池中保持的最小和最大空闲连接数

为什么需要这些配置

多数据源环境下,某些数据源可能较少使用,导致连接长时间空闲。数据库服务器通常会关闭长时间空闲的连接(如MySQL默认8小时)。如果应用尝试使用这些已关闭的连接,就会出现"No operations allowed after connection closed"错误。

通过启用test-while-idle和设置validation-query,连接池会定期验证连接是否有效,及时关闭无效连接并创建新连接,从而避免使用已关闭的连接。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题