java調用“package預存程序”遇到的問題ORA-04068: existing state of packages has been discarded
來源:互聯網
上載者:User
現狀:1. 項目,調用"package 預存程序"問題如下: 當web處於啟動狀態,此時編譯"package 預存程序:SALSEL.PAC_REAL_USERTAG_TEST", 第一次調用該預存程序時,報錯:“Cause: java.sql.SQLException: ORA-04068: existing state of packages has been discardedORA-04061: existing state of package body "SALSEL.PAC_REAL_USERTAG_TEST" has been invalidatedORA-04065: not executed, altered or dropped package body "SALSEL.PAC_REAL_USERTAG_TEST"ORA-06508: PL/SQL: could not find program unit being called: "SALSEL.PAC_REAL_USERTAG_TEST"ORA-06512: at line 1” 再次調用則成功。 2. 問題分析: 由於“package 預存程序”中,使用package,並且使用了全域變數。當oracle編譯此預存程序時,將此預存程序的原狀態置為失效,重新建立了一個新的狀態的預存程序。 導致,第一次調用時,調用的是失效狀態的“package 預存程序”。第二次調用失效狀態的“package 預存程序”。 3. 解決方案: http://blog.csdn.net/ningxuezhu/article/details/8880545 http://database.ctocio.com.cn/tips/14/8106014.shtml 文章中提供了3種解決方案。方案3我們認為是最合適的。需要使用下面的方法,判斷需要環繞通知publicstaticboolean returnExecutionRequired(SQLException e){boolean returnValue= "72000" .equals(e.getSQLState()) && e.getErrorCode()== 4068 ;return returnValue;} 但是,我們的架構,調用預存程序異常時,拋出的異常不是SQLException,而是BusiException。 這樣,我們就無法擷取對應的ErrorCode和SQLState。 4. 最終採用方法 目前,我們的方法是,使用baseDao.getConnection(),自己開啟連結,調用“package 預存程序”,然後關閉Connection. 但是,這樣有個問題,頻繁的開啟資料庫連結,關閉資料庫連結,會造成資源消耗。 看能否從架構層面,拋出SQLException。