首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JDBC 連接 Oracle 報錯 ORA-12505 完整排查指南

     編輯:Java 相關知識

錯誤現象

java.sql.SQLException: Io 異常: Connection refused
(DESCRIPTION=(TMP=)(VSNNUM=186646784)(ERR=12505)
(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))

錯誤碼含義

ORA-12505:TNS:listener does not currently know of SID given in connect descriptor

  • 監聽器正常運行,但不知道連接描述符中指定的 SID
  • 常見原因:JDBC URL 使用了 SID,但實例實際註冊的是 Service Name,或 SID 拼寫錯誤

根因分析:SID vs Service Name

關鍵差異:URL 中冒號 : 後跟 SID,斜杠 / 後跟 Service Name。寫錯分隔符是高頻錯誤。

標準排查步驟

步驟 1:確認數據庫實際實例名/服務名

使用能連接的工具 (PL/SQL Developer、SQL*Plus、DBeaver) 登入數據庫,執行:

-- 查詢實例名 (SID)
SELECT INSTANCE_NAME FROM V$INSTANCE;

-- 查詢服務名
SELECT NAME FROM V$ACTIVE_SERVICES;
-- 或
SHOW PARAMETER SERVICE_NAMES;

記錄返回的具體值,如 ORCL、orcl.example.com、PDB1 等。

步驟 2:驗證監聽器註冊狀態

-- 服務器端執行
lsnrctl status
lsnrctl services

輸出中 Service "ORCL" has 1 instance(s)... 確認服務名與實例映射關係。

步驟 3:修正 JDBC 連接字符串

// 錯誤示範 (用 SID 格式連 Service Name)
jdbc:oracle:thin:@10.209.49.5:1521:orcl.example.com

// 正確格式 1:使用 Service Name (推薦,斜杠分隔)
jdbc:oracle:thin:@10.209.49.5:1521/orcl.example.com

// 正確格式 2:使用 SID (冒號分隔,需確認實例確為 SID)
jdbc:oracle:thin:@10.209.49.5:1521:ORCL

// 完整 TNS 格式 (最穩健,避免分隔符歧義)
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=10.209.49.5)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=orcl.example.com)))

步驟 4:檢查驅動版本兼容性

  • Oracle 19c/21c 需 ojdbc8.jar (Java 8) 或 ojdbc11.jar (Java 11+)
  • 舊驅動 ojdbc6/7 不支援新版數據庫特性,可能導致協商失敗
  • Maven 坐標:com.oracle.database.jdbc:ojdbc8:21.9.0.0

步驟 5:網絡與防火牆驗證

# 服務器端檢查監聽端口
netstat -an | grep 1521
ss -lntp | grep 1521

# 客戶端測試連通性
telnet 10.209.49.5 1521
nc -zv 10.209.49.5 1521

進階場景:PDB (可插拔數據庫) 連接

Oracle 12c+ 多租戶架構下,CDB 根容器與 PDB 有不同服務名:

-- 查詢所有 PDB 服務名
SELECT CON_ID, NAME, OPEN_MODE FROM V$PDBS;
SELECT NAME FROM V$SERVICES WHERE CON_ID > 1;

連接 PDB 必須指定 PDB 的 Service Name,而非 CDB 的 SID:

jdbc:oracle:thin:@host:port/PDB1_SERVICE_NAME

常見誤區速查表

概念說明JDBC URL 格式
SID (System Identifier)實例級標識,Oracle 8i/9i 常用,單實例環境jdbc:oracle:thin:@host:port:SID
Service Name服務級標識,Oracle 9i+ 推薦,支援 RAC/數據庫鏈接jdbc:oracle:thin:@host:port/ServiceName
誤區正確認知
以為 SID 和 Service Name 通用完全不同,分隔符不同,註冊機制不同
複製 tnsnames.ora 內容作為 JDBC URLJDBC Thin 驅動不解析 tnsnames.ora,需展開為完整描述符
認為 12505 是網絡不通網絡不通是 12541/12560/17002;12505 表示監聽器收到請求但找不到服務
只重啟應用不重啟監聽器動態註冊需時間,或執行 ALTER SYSTEM REGISTER 強制註冊

一條龍驗證腳本

# 1. 確認服務名
sqlplus / as sysdba <

總結

ORA-12505 核心是 「監聽器找不到服務」。解決路徑:查實例名 → 確認服務名 → 修正 URL 格式 (斜杠/冒號) → 驗證驅動版本 → 排查網絡。養成使用 Service Name + 斜杠格式 或 完整 TNS 描述符 的習慣,可避免 90% 此類問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved