Listener refused the connection 错误主因是连接数超限(ORA-12519)或服务名/SID不匹配(ORA-12505/12514),需分别查v$process与processes参数、lsnrctl status及JDBC URL格式。
高峰期出现 listener refused the connection with the following error,基本就是数据库服务端扛不住了——不是网络不通,也不是配置写错,而是监听器明确拒绝新连接。核心就两类原因:连接数超限(ora-12519)或服务名/sid不匹配(ora-12505、ora-12514)。下面分情况说清楚怎么做、为什么、容易踩什么坑。
查当前连接数和上限:先确认是不是真满了
别急着改配置,先看数据库实际负载。连上 Oracle(用 sqlplus / as sysdba),执行:
select count(*) from v$process;
再查上限:
select value from v$parameter where name = 'processes';
如果前者接近甚至等于后者,就是连接池打满导致的 ORA-12519。常见于:
- Java 应用用了未回收的连接(比如没
close()或没走连接池) - 多个应用共用一个 Oracle XE 实例(XE 默认
processes=40,一个 Tomcat 就可能占掉 20+) - DBA 工具(PL/SQL Developer、SQL Developer)开着一堆未关闭会话
临时缓解可杀闲置会话:alter system kill session 'sid,serial#';;长期解决必须调大 processes,且需重启数据库生效:alter system set processes = 300 scope = spfile;
立即学习“Java免费学习笔记(深入)”;
JDBC URL 里用冒号还是斜杠:搞错就直接被拒
ORA-12505 和 ORA-12514 都是监听器“不认识你找的那个库”,根源在 JDBC URL 的写法和数据库实际注册的服务名不一致。
Oracle 支持两种连接方式:
-
jdbc:oracle:thin:@host:port:SID—— 冒号结尾,走 SID(实例名) -
jdbc:oracle:thin:@host:port/service_name—— 斜杠结尾,走 Service Name(服务名)
但注意:SID 和 service_name 不一定相同。比如 XE 默认 SID 是 XE,但 service_name 是 XEXDB 或 XE(取决于版本和配置)。查真实值用:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
SELECT value FROM v$parameter WHERE name = 'service_names';
或者查监听注册的服务:lsnrctl status,看输出里 Service "xxx" has 1 instance(s) 那行。
常见坑:
- 开发环境连的是
orcl,测试环境其实是ORCLPDB(多租户 PDB 名) - URL 写成
:orcl,但数据库只注册了orcl.example.com这种全限定 service_name - 改过
tnsnames.ora却忘了重启监听:lsnrctl reload或lsnrctl stop && lsnrctl start
监听器本身没跑或没注册服务:ORA-12541 和 ORA-12514 的区别
ORA-12541: TNS:no listener 是最基础的——压根没监听进程。检查:
- Linux:
ps -ef | grep tnslsnr,没输出就手动启动:lsnrctl start - Windows:服务列表里确认
OracleXETNSListener(XE)或OracleOraDB21Home1TNSListener(企业版)是否运行
ORA-12514: TNS:listener does not currently know of service requested 是监听起来了,但没“认出”你 URL 里的那个服务。原因通常是:
- 数据库实例没启动(
startup没执行),监听无法动态注册服务 - 静态注册没配(
listener.ora里没写SID_LIST),又关了动态注册(local_listener参数为空或错) - 数据库启用了动态注册,但
local_listener指向了错误地址(比如写成localhost而非实际 IP)
验证监听是否知道服务:lsnrctl status 输出中必须有你 URL 里写的 service_name 或 SID 条目。
别忽略网络层和资源竞争:IP、端口、防火墙
有些问题看似数据库,实为中间环节卡住:
- 应用服务器和 DB 服务器之间开了防火墙,1521 端口只放行了部分 IP,高峰期新机器扩容后没加白名单
- Oracle 安装在虚拟机或容器里,宿主机做了 NAT 或端口映射,但只映射了 1521,没映射其他动态端口(如 RAC 的 VIP 或 SCAN)
- 同一台机器上多个 Oracle 实例,都试图绑定 1521,后启动的失败(
lsnrctl status看不到服务) - Java 应用用了连接池(如 HikariCP),但
maxLifetime设得太长,连接复用导致旧连接僵死,新连接不断创建直到打满processes
高峰期暴露的问题,往往不是新 bug,而是平时没压测出的配置边界。重点盯住 v$process、lsnrctl status、JDBC URL 格式这三处,80% 的 Listener refused 就能定位到根上。

















