type
status
date
slug
summary
tags
category
icon
password
js
在使用 Spring Boot + Druid + SQL Server 的项目中,很多开发者会遇到如下错误:
这个错误虽然不常见,但一旦出现就很顽固,可能频繁触发甚至导致业务异常。本文将从原理出发,分析这个错误的根本原因,并提供完整的解决方案,包括日志配置,适用于 Spring Boot 3.4.4 + Druid + 多数据源(如 dynamic-datasource)。

❓ 错误来源解析

这个错误是 SQL Server 抛出的,意思是:
某个连接尝试执行已失效的 PreparedStatement(即“预定义语句”),但其对应的句柄在服务端已被释放。

产生原因:

  • Druid 启用了 poolPreparedStatements 缓存机制
  • 连接被复用时,继续使用旧的 PreparedStatement 句柄(已失效)
  • SQL Server 会主动清除某些预编译语句(尤其是在连接空闲/复用时)

✅ 正确做法:关闭 Druid 的 PreparedStatement 缓存

在使用 SQL Server 的数据源中,必须关闭以下两个参数:
⚠️ 注意:只设置 max-pool-prepared-statement-per-connection-size=20 也会自动触发缓存启用!

✅ 多数据源场景下的完整配置示例

以下为典型的 MySQL + SQL Server 混合场景配置(基于 .properties 文件):

✅ 日志输出配置(logback-spring.xml)

为了更方便地定位问题,我们建议在 Spring Boot 中使用 logback-spring.xml 来开启 Druid、MyBatis、动态数据源的调试日志。

📄 src/main/resources/logback-spring.xml 内容:

✅ 请移除 application.properties 中的 logging.level.xxx 配置,避免冲突。

🧪 启动后预期日志输出

  • 数据源初始化信息:
实际操作中,我的控制台没有打印这些信息,但是可以通过druid页面查看到确实关闭了
  • 数据源切换日志:
  • SQL 执行日志(带慢 SQL 时间):

✅ 补充建议

场景
建议
生产环境
日志级别建议调低至 INFO,仅打印慢 SQL
SQL Server 数据源
避免使用 Druid 缓存机制,或切换为 HikariCP
Druid 慢 SQL 日志
使用 filters=stat + slowSqlMillis=500 输出慢 SQL
MyBatis SQL 日志
配合 logback 打印执行语句,便于调优

📌 依赖版本参考

  • Spring Boot:3.4.4
  • Druid:1.2.20+
  • SQL Server JDBC Driver:com.microsoft.sqlserver:mssql-jdbc:12.6.1.jre11
  • Dynamic Datasource Starter:3.4.4
  • MyBatis Plus:3.5+

✅ 总结

问题
原因
正确做法
找不到预定义语句句柄
SQL Server 回收已缓存的句柄
关闭 Druid 的 PreparedStatement 缓存
日志无输出
默认配置不打印 Druid 日志
使用 logback-spring.xml 显式开启日志
SQL 不可见
没有启用 stat filter
添加 filters=stat 与日志配合使用

有任何配置问题或 Spring Boot 项目调优相关问题,欢迎留言交流 👍
如何做出网页版在线聊天时,有新消息浏览器标签闪烁的效果Ollama运行报错
Loading...
吕行者
吕行者
吕行者
最新发布
Spring Boot + Druid + SQL Server 报错 “找不到句柄为 X 的预定义语句” 的解决方案(含日志配置)
2025-7-11
Ollama运行报错
2025-7-4
Hutool的MailUtil设置发件人别名
2025-5-16
Dify设置网络代理
2025-4-22
mysql-connector-j 8.4 启动慢的问题
2025-4-22
Ubuntu安装Dify实录
2025-4-8