1. 程式人生 > >ORACLE中SID和SERVICE_NAME的區別

ORACLE中SID和SERVICE_NAME的區別

spring 好的 java應用程序 系列 sdn 文件 數據 jdbc 修改

先來講一個小故事,2015年6月份,有個客戶遷移了數據庫,由單實例數據庫變成了RAC。JAVA應用程序出現了無法連接數據庫的情況,但是PL/SQL能連接上數據庫。由於項目比較龐大,雖然在半夜切換的,但是也不能接受長時間的業務停頓。當時,我對ORACLE技術也只是略知皮毛。在咨詢過公司研發後,他們給我的建議是:參考PL/SQL的連接參數,將spring中jdbc連接的url由jdbc:oracle:thin:@10.2.0.2:1521:orcl改為jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =(PROTOCOL = TCP)(HOST = 10.2.0.2)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = orcl))),結果問題解決了,當時我挺佩服公司研發的。現在看來,這個並不是最佳的解決方案,下面通過講解SID和SERVICE_NAME的區別,我將給出更佳的解決方案。

在講解SID和SERVICE_NAME之前,先說一下實例。實例是操作系統中訪問數據庫所需要的一系列的進程和內存的集合。即使沒有任何數據文件,實例也可以啟動。但是要想訪問數據庫,必須把數據庫文件加載進實例中。實例和數據庫的區別可以簡單概括為:實例是臨時的,它只在相關的進程和內存集合存在時存在,而數據庫是永久的,只要文件存在它就存在。一個實例只能對應一個數據庫,但是一個數據庫可以由多個實例對應(如RAC)。RAC就是多個實例同時打開一個數據庫文件的系統,在結構上是多臺機器,每臺機器運行一個實例,每個實例都打開同一個數據庫 (這個是用磁盤共享技術實現的),這些實例之間需要同步高速緩存,這樣保證多個實例是完全一致的,不會相互沖突乃至覆蓋。

SID即INSTANCE_NAME是用來唯一標示實例的。SERVICE_NAME是oracle8i新引進的,8i之前,一個數據庫只能由一個實例對應,但是隨著高性能的需求,並行技術的使用,一個數據庫可以由多個實例對應了,比較典型的應用如RAC。為了充分利用所有實例,並且令客戶端連接配置簡單,ORACLE提出了SERVICE_NAME的概念。該參數直接對應數據庫,而不是某個實例。

了解了SID和SERVICE_NAME之後,我突然覺得前面故事中使用的解決方案並不是最佳的解決方案,因為SERVICE_NAME的出現就是為了應對並發技術,簡化客戶端連接配置。通過SERVICE_NAME應該能找到更好的解決方案。通過查找JDBC幫助得知JDBC連接ORACLE的方法由三種:

格式一:jdbc:oracle:thin:@//<host>:<port>/<service_name>
格式二:jdbc:oracle:thin:@<host>:<port>:<SID>
格式三:jdbc:oracle:thin:@<TNSName>

不難看出,故事中使用RAC之前,JDBC是使用格式二連接的,使用RAC後實例增多了,SID已經不唯一,格式二已經無法完全利用所有資源。研發參考PL/SQL的連接方法剛好碰巧使用了格式三。因為java應用服務器跟數據庫服務器是分離的,應用服務器上沒有oracle的服務端以及客戶端。雖然解決方案中沒有使用TNSName,但是使用了TNSName的連接描述,效果是一樣的。既然JDBC有三種連接方案,我們不妨再看一下第一種方案。再加上前面的講解內容,我想大家已經都知道故事中的問題該怎麽修改了,只要改成jdbc:oracle:thin:@//10.2.0.2:1521/orcl就可以了,而且這種格式也支持單實例數據庫。這也是ORACLE在8i之後增加SERVICE_NAME的初衷。

通過這個故事,我們可以看到,只有充分了解了ORACLE的知識,才能更好的使用ORACLE技術。
---------------------
作者:張振磊
來源:CSDN
原文:https://blog.csdn.net/zhangzl1012/article/details/50752572
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

ORACLE中SID和SERVICE_NAME的區別