ORA-12516错误源于数据库processes/sessions参数耗尽,非网络或密码问题;需先查v$process和v$parameter确认占用与上限,再杀inactive会话临时释放,最后按sessions=1.1×processes+5同步调大两参数并重启数据库生效。
ora-12516 不是网络不通或密码错,而是数据库进程池已满——连接请求被监听器直接拒收,必须从 processes 和 sessions 参数入手,否则改 url 或重连毫无作用。
查当前进程和上限:先确认是不是真满了
很多同学一看到 ORA-12516 就急着改代码或重启应用,但真正卡点在数据库端。用 sysdba 登录后执行:
-
SELECT COUNT(*) FROM v$process;—— 实际占用的 OS 进程数 -
SELECT value FROM v$parameter WHERE name = 'processes';—— 当前允许的最大值 -
SELECT COUNT(*) FROM v$session;和SHOW PARAMETER sessions;—— 对应会话层限制
如果前者接近或等于后者(比如 149/150),就是硬性资源耗尽,不是连接泄漏,也不是 JDBC 配置问题。
临时释放连接:杀 inactive 会话比重启更安全
紧急恢复服务时,别第一时间 kill -9 或重启监听器。优先清理“挂住”的空闲连接:
SELECT sid, serial#, username, status, machine, program FROM v$session WHERE status = 'INACTIVE' AND username IS NOT NULL ORDER BY last_call_et DESC;- 挑出长时间 idle 且非关键应用的会话,执行:
ALTER SYSTEM KILL SESSION '123,45678' IMMEDIATE; - 避免杀
username为空的后台进程(如DBW0、LGWR),也别杀status = 'ACTIVE'的业务会话
注意:KILL SESSION 不等于操作系统级 kill,它由 Oracle 自行清理资源,更可控。
立即学习“Java免费学习笔记(深入)”;
永久扩容:processes 和 sessions 必须同步调大
processes 是底层 OS 进程上限,sessions 是上层会话逻辑上限,二者不匹配会导致 ORA-12516 反复出现:
- 修改必须用
SCOPE=SPFILE(写入持久化参数文件),MEMORY无效 -
sessions值不能随便设,Oracle 内部公式是sessions = 1.1 × processes + 5,例如设processes=300,则sessions至少为335 - 执行顺序必须是:
ALTER SYSTEM SET processes=300 SCOPE=SPFILE;→ALTER SYSTEM SET sessions=335 SCOPE=SPFILE;→SHUTDOWN IMMEDIATE;→STARTUP; - 重启后务必验证:
SHOW PARAMETER processes;和SHOW PARAMETER sessions;,确保值已加载
Java 应用侧配合:别让连接池雪上加霜
即使数据库扩容了,如果应用端连接池配置不当,仍可能快速打满新上限:
- 检查 HikariCP / Druid 等连接池的
maximumPoolSize,别设成 200+ 还长期 hold 连接 - 确认
connectionTimeout和idleTimeout合理(建议idleTimeout ≤ 10分钟) - 避免在事务外长期持有 connection(如 service 层没关 try-with-resources)
- 特别注意:Spring Boot 默认 HikariCP 的
connection-test-query若设为SELECT 1,在 Oracle 12c+ 上可能触发额外 session,建议用isValid()替代
最常被忽略的一点:processes 调大后,操作系统级限制(如 Linux 的 ulimit -n)可能成为新瓶颈,尤其当值超过 1024 时,需同步调整系统 limits.conf。


















