【ojdbc14.jar】由於Oracle驅動ojdbc14.jar導致千萬富翁破產之始末
這是一個“千萬富翁”瞬間變為“貧民”的真實過程。且聽我慢慢道來。
1.故障模擬過程
1)先看一段JAVA程式碼對字串讀取轉換後的數值表示形式的差異
這段程式碼實現的功能是從平文字檔案中將字串表示形式的內容轉化為數值並列印出結果。
Normal 0 false false false EN-US ZH-CN X-NONEpackage org.seco.sclcore.test; import java.math.BigDecimal; public class Sample { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(getSalesMoney("26947280")); System.out.println(getSalesMoney("122936367")); } public static BigDecimal getSalesMoney(String value) { String stringValue; boolean isNegative = false; if (value.indexOf("-") != -1) { stringValue = value.replace("-", ""); isNegative = true; } else { stringValue = value; } BigDecimal result = BigDecimal.ZERO; if (isNegative) { double doubleValue = -1; result = BigDecimal.valueOf(Double.valueOf(stringValue).doubleValue()).multiply( BigDecimal.valueOf(doubleValue)); } else { result = BigDecimal.valueOf(Double.valueOf(stringValue).doubleValue()); } return result; } }
2)程式碼輸出結果
程式碼中顯式的將"26947280"和"122936367"字串讀取並轉化為數字。結果對應如下:
"26947280" -- 2.694728E+7
"122936367" -- 122936367
規律:字串中以數字零結尾的內容轉化為數字後以2.694728E+7這種科學計數法的形式儲存,而非零幾位的內容還是以原有形式顯式。
重點關注科學計數法表示的結果,此處"26947280"結尾處的零已被去掉。2.694728E+7這種科學計數法表示的數字就是數字26947280,此處沒有問題。
3)入庫後故障出現
JAVA程式碼將結果儲存到Oracle資料庫後,詭異的事情發生了。原先以科學計數法顯示的2.694728E+7數值被存入Oracle資料庫後變成了26.9472,如下所示。
錯誤值 實際值
26.9472 26947280
這種錯誤是絕對無法容忍的。
原本將近兩千七百萬人民幣的資產幻滅了,變成了不到二十七元人民幣。這是何等的荒謬,誰都是無法承受這種從千萬富翁變為貧民的打擊。
2.故障分析過程
看到這個荒謬的錯誤後我們需要做的是冷靜、冷靜……還是冷靜。
仔細的去分析導致這個錯誤的最終原因到底在哪裡。
1)第一種推測:JAVA本身的問題
這種可能性基本可以排除。因為在我們的測試程式碼中返回的數值上看,即便數字表示形式不一樣(科學計數法與否),但是最終轉化為數值是忠於原字串本身內容的。也就是說2.694728E+7就是表示26947280,122936367還是其自身。
2)第二種推測:Oracle資料庫本身的問題
這種可能性也站不住腳,試想一下,作為一款大牌商業資料庫軟體的Oracle怎麼會隨隨便便將客戶的資料篡改呢。
Oracle會將應用程式傳過來的內容原原本本的存放到資料庫中,用於後續的展示或處理。
3)第三種推測:問題出在應用程式和Oracle資料庫之間
JAVA應用程式是透過ojdbc14.jar這個驅動程式與Oracle資料庫進行銜接的。莫非問題出在這個環節?
(1)檢視當前ojdbc14.jar檔案的版本
版本檢視方法:可以使用解壓軟體開啟ojdbc14.jar檔案,檢視META-INF資料夾中的MANIFEST.MF檔案,內容如下:
Manifest-Version: 1.0
Specification-Title: Oracle JDBC driver classes for use with JDK14
Sealed: true
Created-By: 1.4.2_08 (Sun Microsystems Inc.)
Implementation-Title: ojdbc14.jar
Specification-Vendor: Oracle Corporation
Specification-Version: Oracle JDBC Driver version - "10.2.0.1.0"
Implementation-Version: Oracle JDBC Driver version - "10.2.0.1.0"
Implementation-Vendor: Oracle Corporation
Implementation-Time: Wed Jun 22 11:19:45 2005
Name: oracle/sql/converter/
Sealed: false
Name: oracle/sql/
Sealed: false
Name: oracle/sql/converter_xcharset/
Sealed: false
可見,這裡使用的是10.2.0.1.0這個10g版本中的最基礎的驅動程式。
(2)嘗試下載10g最新的驅動程式重新測試
10g的最新ojdbc14.jar檔案的版本資訊如下:
Manifest-Version: 1.0
Specification-Title: Oracle JDBC driver classes for use with JDK14
Sealed: true
Created-By: 1.4.2_14 (Sun Microsystems Inc.)
Implementation-Title: ojdbc14.jar
Specification-Vendor: Oracle Corporation
Specification-Version: Oracle JDBC Driver version - "10.2.0.5.0"
Implementation-Version: Oracle JDBC Driver version - "10.2.0.5.0"
Implementation-Vendor: Oracle Corporation
Implementation-Time: Thu Apr 8 03:40:31 2010
Name: oracle/sql/converter/
Sealed: false
Name: oracle/sql/
Sealed: false
Name: oracle/sql/converter_xcharset/
Sealed: false
10g最新版本的驅動是10.2.0.5.0。
在更換了驅動程式之後,之前的故障迎刃而解。原來罪魁禍首就是APP與DB之間的驅動程式ojdbc14.jar。
3.故障處理方法
透過上面的分析過程已經確認是Oracle驅動程式ojdbc14.jar版本過低導致的,因此故障處理方法很直接,替換生產環境中10.2.0.1版本的驅動為10.2.0.5驅動。
4.小結
本文中提到的故障場景影響是很惡劣的。即便在替換驅動後依然有很多善後工作要做,比如將已經入庫的錯誤資料的查詢並調整正確。
在JAVA應用程式和資料庫之間的驅動選取方面需要注意,基本要求,保證驅動版本和資料庫的版本保持一致,或者使用較新版本的驅動程式。
這個故障帶給我們的啟示是:任何一個環節都有可能存在重大的隱患,細緻嚴謹永遠是IT人最重要的職業素質。
Good luck.
secooler
12.03.09
-- The End --
1.故障模擬過程
1)先看一段JAVA程式碼對字串讀取轉換後的數值表示形式的差異
這段程式碼實現的功能是從平文字檔案中將字串表示形式的內容轉化為數值並列印出結果。
Normal 0 false false false EN-US ZH-CN X-NONEpackage org.seco.sclcore.test; import java.math.BigDecimal; public class Sample { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(getSalesMoney("26947280")); System.out.println(getSalesMoney("122936367")); } public static BigDecimal getSalesMoney(String value) { String stringValue; boolean isNegative = false; if (value.indexOf("-") != -1) { stringValue = value.replace("-", ""); isNegative = true; } else { stringValue = value; } BigDecimal result = BigDecimal.ZERO; if (isNegative) { double doubleValue = -1; result = BigDecimal.valueOf(Double.valueOf(stringValue).doubleValue()).multiply( BigDecimal.valueOf(doubleValue)); } else { result = BigDecimal.valueOf(Double.valueOf(stringValue).doubleValue()); } return result; } }
2)程式碼輸出結果
程式碼中顯式的將"26947280"和"122936367"字串讀取並轉化為數字。結果對應如下:
"26947280" -- 2.694728E+7
"122936367" -- 122936367
規律:字串中以數字零結尾的內容轉化為數字後以2.694728E+7這種科學計數法的形式儲存,而非零幾位的內容還是以原有形式顯式。
重點關注科學計數法表示的結果,此處"26947280"結尾處的零已被去掉。2.694728E+7這種科學計數法表示的數字就是數字26947280,此處沒有問題。
3)入庫後故障出現
JAVA程式碼將結果儲存到Oracle資料庫後,詭異的事情發生了。原先以科學計數法顯示的2.694728E+7數值被存入Oracle資料庫後變成了26.9472,如下所示。
錯誤值 實際值
26.9472 26947280
這種錯誤是絕對無法容忍的。
原本將近兩千七百萬人民幣的資產幻滅了,變成了不到二十七元人民幣。這是何等的荒謬,誰都是無法承受這種從千萬富翁變為貧民的打擊。
2.故障分析過程
看到這個荒謬的錯誤後我們需要做的是冷靜、冷靜……還是冷靜。
仔細的去分析導致這個錯誤的最終原因到底在哪裡。
1)第一種推測:JAVA本身的問題
這種可能性基本可以排除。因為在我們的測試程式碼中返回的數值上看,即便數字表示形式不一樣(科學計數法與否),但是最終轉化為數值是忠於原字串本身內容的。也就是說2.694728E+7就是表示26947280,122936367還是其自身。
2)第二種推測:Oracle資料庫本身的問題
這種可能性也站不住腳,試想一下,作為一款大牌商業資料庫軟體的Oracle怎麼會隨隨便便將客戶的資料篡改呢。
Oracle會將應用程式傳過來的內容原原本本的存放到資料庫中,用於後續的展示或處理。
3)第三種推測:問題出在應用程式和Oracle資料庫之間
JAVA應用程式是透過ojdbc14.jar這個驅動程式與Oracle資料庫進行銜接的。莫非問題出在這個環節?
(1)檢視當前ojdbc14.jar檔案的版本
版本檢視方法:可以使用解壓軟體開啟ojdbc14.jar檔案,檢視META-INF資料夾中的MANIFEST.MF檔案,內容如下:
Manifest-Version: 1.0
Specification-Title: Oracle JDBC driver classes for use with JDK14
Sealed: true
Created-By: 1.4.2_08 (Sun Microsystems Inc.)
Implementation-Title: ojdbc14.jar
Specification-Vendor: Oracle Corporation
Specification-Version: Oracle JDBC Driver version - "10.2.0.1.0"
Implementation-Version: Oracle JDBC Driver version - "10.2.0.1.0"
Implementation-Vendor: Oracle Corporation
Implementation-Time: Wed Jun 22 11:19:45 2005
Name: oracle/sql/converter/
Sealed: false
Name: oracle/sql/
Sealed: false
Name: oracle/sql/converter_xcharset/
Sealed: false
可見,這裡使用的是10.2.0.1.0這個10g版本中的最基礎的驅動程式。
(2)嘗試下載10g最新的驅動程式重新測試
10g的最新ojdbc14.jar檔案的版本資訊如下:
Manifest-Version: 1.0
Specification-Title: Oracle JDBC driver classes for use with JDK14
Sealed: true
Created-By: 1.4.2_14 (Sun Microsystems Inc.)
Implementation-Title: ojdbc14.jar
Specification-Vendor: Oracle Corporation
Specification-Version: Oracle JDBC Driver version - "10.2.0.5.0"
Implementation-Version: Oracle JDBC Driver version - "10.2.0.5.0"
Implementation-Vendor: Oracle Corporation
Implementation-Time: Thu Apr 8 03:40:31 2010
Name: oracle/sql/converter/
Sealed: false
Name: oracle/sql/
Sealed: false
Name: oracle/sql/converter_xcharset/
Sealed: false
10g最新版本的驅動是10.2.0.5.0。
在更換了驅動程式之後,之前的故障迎刃而解。原來罪魁禍首就是APP與DB之間的驅動程式ojdbc14.jar。
3.故障處理方法
透過上面的分析過程已經確認是Oracle驅動程式ojdbc14.jar版本過低導致的,因此故障處理方法很直接,替換生產環境中10.2.0.1版本的驅動為10.2.0.5驅動。
4.小結
本文中提到的故障場景影響是很惡劣的。即便在替換驅動後依然有很多善後工作要做,比如將已經入庫的錯誤資料的查詢並調整正確。
在JAVA應用程式和資料庫之間的驅動選取方面需要注意,基本要求,保證驅動版本和資料庫的版本保持一致,或者使用較新版本的驅動程式。
這個故障帶給我們的啟示是:任何一個環節都有可能存在重大的隱患,細緻嚴謹永遠是IT人最重要的職業素質。
Good luck.
secooler
12.03.09
-- The End --
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-718209/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【轉】【ojdbc14.jar】由於Oracle驅動ojdbc14.jar導致千萬富翁破產之始末JDBCJAROracle
- Oracle驅動classes12.jar 與ojdbc14.jar的區別OracleJARJDBC
- 【故障處理】由於ojdbc14.jar版本不正確導致ORA-01461和ORA-01483故障的處理JDBCJAR
- 換ojdbc14.jar驅動後clob欄位後臺報異常的解決JDBCJAR
- ojdbc14.jar 與 classes12.jarJDBCJAR
- AIX下由於nfs故障導致oracle hangAINFSOracle
- 由drop datafile導致的oracle bugOracle
- java由於越界導致的報錯Java
- Oracle JDBC驅動使用setDate()、setTimestamp()導致全表掃描OracleJDBC
- oracle兩節點RAC,由於gipc導致某節點crs無法啟動問題分析Oracle
- [Oracle]由於初始化引數檔案修改錯誤導致oracle無法startupOracle
- 由於無法分配ip而導致的FailedCreatePodSandBoxAI
- Oracle目錄由於TFA觸發bug導致jdb檔案未自動清理引起空間不足Oracle
- 由於gcc軟體包沒有安裝導致的Oracle安裝失敗GCOracle
- 驅動導致的當機怎麼解決
- 解決辦法:由於oracle版本不同導致匯入資料時失敗Oracle
- 一起由於Oracle 8.1.6 BUG而導致的ORA-03113錯誤Oracle
- Microsoft承認Windows由於永久性記憶體而導致啟動緩慢ROSWindows記憶體
- 由於網路卡故障導致DATAGUARD傳輸檔案失敗
- openGauss 由於RemoveIPC未關閉導致資料庫crashREM資料庫
- ORACLE windows驅動磁碟機代號自動變更導致oracle資料庫崩潰無法啟動OracleWindows資料庫
- Laravel 關聯模型由於名稱一致性導致的問題Laravel模型
- 由AIX系統故障導致系統重啟,使Oracle資料庫自動啟動例項AIOracle資料庫
- tomcat 由於 -Xss 太小導致無法載入應用Tomcat
- spring boot 2.0.0由於版本不匹配導致的NoSuchMethodError問題解析Spring BootError
- 伺服器由於防火牆問題導致埠不通解決方法伺服器防火牆
- 由於字符集問題導致 Package Body created with compilation errors.PackageError
- 【shmmax】由於shmmax設定過小導致dbca建庫無法完成HMM
- 【DB2學習】由於TSM損壞導致歸檔失敗DB2
- 關於Oracle OCI驅動的使用Oracle
- 【案例】Oracle報錯ORA-01194 ORA-01110 由於資料庫SCN不一致導致無法啟動Oracle資料庫
- Linux平臺由於OPROCD程式導致伺服器重啟的問題Linux伺服器
- 由hugepage設定導致的資料庫事故資料庫
- Oracle RAC啟動因CTSS導致的異常Oracle
- redat 5.8由於檔案系統100%,導致oracle資料庫例項掛起處理例項Oracle資料庫
- 由adoacorectl.sh啟動失敗導致網頁無法顯示網頁
- MYSQL 5.7 升級 8.0 後的 由於字符集導致的大問題 ?MySql
- Asp.netcore中由於頁面編碼導致的中文亂碼ASP.NETNetCore