You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

排查java.sql.SQLNonTransientConnectionException连接不存在异常

问题背景

Windows服务器上运行的高并发多线程Java应用,负责接收XML请求并转换为SQL,提交至IBM iSeries数据库执行。此前运行稳定,近期随机出现流程中断,错误为:java.sql.SQLNonTransientConnectionException: The connection does not exist。

异常流程固定:

  1. 接收请求
  2. 转换为SQL
  3. 新建/复用数据库连接
  4. 执行SQL并获取结果
  5. 提交事务
  6. 关闭连接
  7. 触发上述连接不存在错误

异常场景下事务耗时约19000ms,正常场景不足40ms。堆栈跟踪如下:

2023.11.09,18:31:13.573,com.***.server.sql.***SQLTransactionProcessor,closeStatement,RMI TCP Connection(5855)-10.11.170.101,XXX1123820-50,1,SQL_XXX_Some_Transaction_ID,SQL Transaction Processor - Closing SQL Statement results in this error: The connection does not exist. 
    java.sql.SQLNonTransientConnectionException: The connection does not exist.
    at com...SQLTransactionProcessor.rollback(***SQLTransactionProcessor.java:642)
    at com...***RequestProcessorImpl$TransactionProcessorTracker.releasePooledProcessors(***RequestProcessorImpl.java:812)
    at com...***RequestProcessorImpl.processRequest(***RequestProcessorImpl.java:225)
    at com...***ServerImpl.submit(***ServerImpl.java:203)
    at sun.reflect.GeneratedMethodAccessor43.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    at sun.rmi.transport.Transport$2.run(Unknown Source)
    at sun.rmi.transport.Transport$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.access$400(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

代码缺陷已发现:捕获SQLException仅打印警告未输出完整栈,异常后仍尝试关闭连接触发报错。计划修改JDBC连接串为jdbc:as400://some.host.name/DATA_BASE_NAME; toolbox trace=all;trace=true;server trace=126;并补充异常栈打印。


需求解答

1. 推测合理性分析

你提出的多线程时序冲突导致连接被误销毁有理论可能性,但概率较低——主流连接池(HikariCP、Apache DBCP等)都做了严格的线程安全控制,连接的获取、归还、回收逻辑不会出现跨线程误操作。

结合异常时长(19000ms远超正常40ms),更核心的原因是SQL执行超时引发连接被提前销毁:

  • 连接池配置的removeAbandonedTimeout、maxWait等参数,可能将长时间未完成的事务连接判定为"废弃连接"并强制回收;
  • IBM i端可能主动断开了长时间无响应的连接(比如数据库层面的超时设置);
  • 线程在连接被销毁后仍尝试执行关闭操作,触发"The connection does not exist"错误。

2. 额外排查思路

  • 检查连接池核心参数:重点核对removeAbandoned、removeAbandonedTimeout、maxWait、validationInterval,确认是否会误回收未完成的长事务连接;
  • 排查IBM i端资源瓶颈:用WRKOBJLCK查看锁等待、WRKACTJOB查看作业负载、DSPLOG TYPE(*SQL)查看SQL相关系统日志,确认是否因数据库资源不足导致SQL执行超时;
  • 分析慢SQL:提取异常事务对应的SQL,在IBM i端用RUNSQLSTM执行并通过EXPLAIN查看执行计划,排查索引失效、全表扫描等问题;
  • 追踪连接生命周期:在代码中添加连接获取/归还的日志,标记线程ID和连接ID,排查是否存在连接泄漏;
  • 验证连接池线程安全性:若使用自定义或老旧版本连接池,检查连接管理逻辑是否存在线程安全漏洞。

3. 具体问题解决

3.1 Windows客户端与IBM i端开启调试

  • Windows Java客户端:
    • 你计划的JDBC连接串参数有效,会生成jt400Trace.out日志文件记录全量跟踪信息;
    • 补充JVM参数强化跟踪:-Djavax.net.debug=all(跟踪网络连接细节)、-Dcom.ibm.as400.access.Trace=all(补充Toolbox详细日志);
  • IBM i数据库端:
    • 开启作业跟踪:STRDBG JOB(目标作业名)或STRUSRPRF USRPRF(目标用户名) TRC(*ON);
    • 查看SQL日志:DSPLOG TYPE(*SQL)或WRKSQLJOB;
    • 启动性能监控:STRPFRMON捕获异常时段的数据库资源使用情况。

3.2 导出实际生效的SQL连接参数

  • Java端:
    • 通过连接对象获取:调用Connection.getMetaData(),打印getURL()、getUserName()等信息;
    • 连接池配置输出:在应用启动阶段,打印连接池所有配置参数(含默认值),确认validationQuery、minEvictableIdleTimeMillis等参数是否生效;
  • IBM i端:
    • 查看作业属性:WRKACTJOB找到目标数据库作业,进入详情后选择Display job attributes查看连接超时、权限等配置;
    • 查看数据库目录:DSPRDBDIRE查看IBM i端默认连接配置。

3.3 捕获异常并安全终止流程的风险

直接捕获异常终止流程存在数据不一致和资源泄漏风险:

  • 若事务已部分执行,直接终止可能导致数据状态异常(事务可能已提交或回滚失败);
  • 未清理Statement、ResultSet等资源会引发连接泄漏,加剧连接池问题。

正确处理方式:

  1. 捕获异常后先检查事务状态,若未提交则尝试回滚(需捕获回滚异常);
  2. 强制清理所有数据库资源(Statement、ResultSet);
  3. 若连接仍可用则归还至连接池,否则标记连接为无效(通知连接池销毁);
  4. 记录完整异常栈、事务ID、SQL语句、线程ID等上下文信息;
  5. 给客户端返回明确错误响应,避免重复请求。

内容的提问来源于stack exchange,提问作者tarekahf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 23:51:01