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

PostgreSQL连接未关闭出现空闲事务导致连接繁忙问题排查

PostgreSQL 大量idle in transaction连接问题排查方案

状态本质说明

idle in transaction 指连接已经开启事务,最后一条SQL执行完成后,事务始终没有执行提交或回滚操作,连接会一直持有数据库资源不释放,累计到一定数量就会导致连接池占满、业务无法获取新连接。
你观察到的元数据查询是ORM类框架(如Hibernate、MyBatis、Spring Data JPA等)自动触发的,用于获取表字段的约束、自增属性、类型等元信息,用于实体类和表结构的映射校验,无需手动编写代码调用,对应SQL如下:

SELECT c.oid, a.attnum, a.attname, c.relname, n.nspname, 
       a.attnotnull OR (t.typtype = 'd' AND t.typnotnull),
       a.attidentity != '' OR pg_catalog.pg_get_expr(d.adbin, d.adrelid) LIKE '%nextval(%' 
FROM pg_catalog.pg_class c 
  JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid) 
  JOIN pg_catalog.pg_attribute a ON (c.oid = a.attrelid) 
  JOIN pg_catalog.pg_type t ON (a.atttypid = t.oid) 
  LEFT JOIN pg_catalog.pg_attrdef d ON (d.adrelid = a.attrelid AND d.adnum = a.attnum) 
  JOIN (SELECT 21826 AS oid , 9 AS attnum UNION ALL SELECT 21826, 3) vals ON (c.oid = vals.oid AND a.attnum = vals.attnum)

常见触发原因

  • 事务默认配置错误:项目全局配置了autocommit=false,所有SQL执行都会默认开启事务,框架执行完元数据查询后没有主动提交事务,直接把连接放回连接池,事务就会一直挂着
  • 连接池回收规则失效:连接池没有开启废弃连接回收开关,或者回收超时时间设置过长,异常场景下事务没有回滚的话,会一直占用连接
  • 框架本身Bug:部分旧版本ORM框架存在元数据查询时申请连接、执行完查询后漏提交/回滚事务的已知问题,属于框架代码缺陷
  • 全局事务切面逻辑异常:如果配置了全局事务切面,把框架内部的元数据查询也纳入了事务管理,但切面的异常分支没有触发事务回滚,也会导致事务悬挂

排查与修复步骤

  1. 临时止损:如果业务已经出现连接不足的问题,执行以下SQL杀掉挂起超过5分钟的空闲事务连接:
SELECT pg_terminate_backend(pid) FROM pg_stat_activity 
WHERE state = 'idle in transaction' AND state_change < NOW() - INTERVAL '5 minute';
  1. 检查连接配置:确认连接参数中autocommit是否为true,连接池是否开启了废弃连接回收,建议将回收超时时间设置为30-60秒,同时开启回收日志,定位连接泄漏的调用栈
  2. 核对框架版本:查询你使用的ORM框架官方更新日志,确认当前版本是否存在元数据查询泄漏事务的已知Bug,如有则直接升级到修复后的稳定版本
  3. 校验全局事务配置:检查是否有全局事务切面错误拦截了框架内部的元数据查询请求,调整切面的切点范围,仅拦截业务层的事务操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:45:01