已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
背景
维护一个 QPS 5000+ 的交易链路,下游 DB 层存在偶发 P99 300ms+ 的抖动。当上游超时后,发现 JDBC 连接池中仍有大量「孤儿工作」占用资源,导致线程池和连接池容量被拖垮。
现象
Statement.cancel() 后,MySQL 8.0 的查询会抛出 SQLException("Query was cancelled"),但 PostgreSQL 的查询仍会阻塞到结果返回;cancel() 实际调用了 KILL QUERY,而 PostgreSQL JDBC 42.6.0 的 cancel() 仅关闭客户端 socket,服务端仍会返回结果;cancel() 对线程池的「孤儿工作」止损效果差异显著。已尝试
cancel() 是通过 KILL QUERY 实现,但需要 thread_id,且 KILL 本身有 5ms 开销;cancel() 只能中断正在执行的查询,但无法处理已发出的 SELECT;socketTimeout=1000 和 connectTimeout=1000,但对阻塞在 SocketInputStream.read() 的线程无效。期望答案
Thread.interrupt() 对 JDBC 是否有效?StructuredTaskScope?已读参考:
cancel() 的局限性;