現狀:
1. 項目,調用"package 存儲過程"問題如下:
當web處於啟動狀態,此時編譯"package 存儲過程:SALSEL.PAC_REAL_USERTAG_TEST",
第一次調用該存儲過程時,報錯:
“
Cause: java.sql.SQLException: ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "SALSEL.PAC_REAL_USERTAG_TEST" has been invalidated
ORA-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. 解決方案:
文章中提供了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。