1. 最近公司產品改用springboot開發, 要支持企業級大型數據庫Oracle ,並且版本要求比較高,需要使用Oracle12c以上.
又因為Oracle 12c 以上有了一個PDB的可插拔數據庫的概念. 之前公司同事要求使用非PDB模式進行建賬套使用, 所以最近的很多機器都是簡單的non-PDB模式的.
這幾天有同事自行搭建數據庫, 使用了PDB模式,結果發現springboot注冊數據庫時報錯,經過自己的搜索和實驗, 問題和思路主要如下:
2. 問題現象. 注冊完數據庫之后,
datasource: type: com.zaxxer.hikari.HikariDataSource url: jdbc:oracle:thin:@10.24.14.56:1521:pdbora12c^M driver-class-name: oracle.jdbc.driver.OracleDriver^M username: gscloud^M password: Test6530^M
啟動會報錯:
java.sql.SQLException: Listener refused the connection with the following error: ORA-12505, TNS:listener does not currently know of SID given in connect descriptor at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:854) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0] at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:793) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0] at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:57) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0] at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:747) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0] at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:562) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0] at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136) ~[HikariCP-3.2.0.jar!/:na] at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369) ~[HikariCP-3.2.0.jar!/:na] at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198) ~[HikariCP-3.2.0.jar!/:na] at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467) [HikariCP-3.2.0.jar!/:na] at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541) [HikariCP-3.2.0.jar!/:na] at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) [HikariCP-3.2.0.jar!/:na] at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) [HikariCP-3.2.0.jar!/:na] at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:158) [spring-jdbc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE] at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:116) [spring-jdbc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE] at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:226) [spring-jdbc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE] at com.sun.proxy.$Proxy696.prepareStatement(Unknown Source) [na:na]
解決思路:
替換連接字符串為:
修改點有兩處:
1. @后面添加兩個 正斜線
2.端口號后面將之前的冒號修改為 正斜線.
datasource: type: com.zaxxer.hikari.HikariDataSource url: jdbc:oracle:thin:@//10.24.14.56:1521/pdbora12c^M driver-class-name: oracle.jdbc.driver.OracleDriver^M username: gscloud^M password: Test6530^M
3. 再次啟動
驗證服務能夠正常啟動起來.
這里面轉帖一下別人對SID和SERVICE_NAME的簡單說明.
3.1 java連接Oracle數據庫的三種格式:
格式一:jdbc:oracle:thin:@//<host>:<port>/<service_name> 格式二:jdbc:oracle:thin:@<host>:<port>:<SID> 格式三:jdbc:oracle:thin:@<TNSName>
3.2 service_name 和sid的區別:
Service_name:該參數是由oracle8i引進的。在8i以前,使用SID來表示標識數據庫的一個實例,但是在Oracle的並行環境中,一個數據庫對應多個實例,這樣就需要多個網絡服務名,設置繁瑣。為了方便並行環境中的設置,引進了Service_name參數,該參數對應一個數據庫,而不是一個實例,而且該參數有許多其它的好處。該參數的缺省值為Db_name. Db_domain,即等於Global_name。一個數據庫可以對應多個Service_name,以便實現更靈活的配置。該參數與SID沒有直接關系,即不必Service name 必須與SID一樣
sid是數據庫實例的名字,每個實例各不相同。