jdbc存儲過程不支持
① JDBC調用存儲過程,存儲過程中事務回滾,報錯
ConnCloseThread中關閉連接的時候,不是立刻返回的。Connection.close()會觸發Connection.commit(),而因為調用的存儲過程中,存儲過程起了自己的事務,connection.commit()必須等到存儲過程結束才能完成(這個是microsoft論壇上看到的)。如果所有connection.close()都等到tx commit或rollback完成才執行的話,這個問題就不會出現了
從測試結果來看,凡是close connection耗時比execute statement短的,連接(物理連接)都會報出該問題。分析原因:通過weblogic datasource獲取的connection並不是物理connection,而是由weblogic wrapped的connection。這些conection在被close後,並不會關閉物理連接,而只是將物理連接還池。我們對connection的所有操作,最終都會被delegated到底層物理連接上,即commit(),rollback()最終都是在物理連接上執行。如果上面的connection.close(),底層物理連接沒有等到存儲過程事務結束就返回的話,那麼物理連接上應該還帶有此次操作的事務,而weblogic這邊不會關系物理連接的情況,直接將連接放入connection pool供其它客戶端使用。這時候如果設定了test on reserve的話,下次客戶端從data source獲取連接時,weblogic會檢查這個物理連接,作一個select操作的,這個有問題的連接就會暴露出來,也就是上面的異常。這個問題如果使用driver manager來獲取連接的話(如果每次都關閉的話),則不會出現,因為使用的物理連接每次都是不同的。還好,weblogic會幫忙重新創建有問題的連接。原因大概了解了,但這是誰的問題呢? 為什麼connection.close()不等存儲過程的事務結束?
結論:一般而言,我們不建議通過JDBC調用存儲過程的時候,在存儲過程中定義事務,應該將tx的管理工作交給jdbc去做。 non-xa如此,xa亦如此,畢竟事務嵌套了以後,管理起來是個問題,完整性更是個問題。
② JDBC調用Sybase存儲過程,結果集總是無法返回,該怎麼處理
JDBC調用Sybase存儲過程,結果集總是無法返回!
java代碼部分如下:
String sproc = "{ call zhouxiaobotest2(?,?,?,?)} ";
CommonDAO = null;
try {
= new CommonDAO(jndi);
Connection connect = .getConn();
//得到總數
rowNum = PageDiv.getCount(countsql.toString(), );
//設置分頁信息
pageBean.setPageInfo(rowNum, pageSize);
// 獲取CallableStatement語句:
CallableStatement mStatement = connect.prepareCall(sproc,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
// 傳入輸入參數和注冊輸出參數
mStatement.setString(1,sql.toString());
mStatement.setInt(2, 10);
mStatement.setInt(3, 10);
mStatement.setInt(4, 5000);
// 執行存儲過程
ResultSet rs = null;
mStatement.execute();
rs = mStatement.getResultSet();
catch (Exception ex) {
ex.printStackTrace();
logger.warn(sql.toString());
} finally {
.destroy();
= null;
sproc = null;
}
存儲過程如下:
create procere zhouxiaobotest @qry varchar(16384),@ipage int, @num int,@maxpages int
as
/*@qry SQL語句, @ipage 頁數, @num 每頁記錄條數, @maxpages 最大查詢頁數 */
begin
declare @execsql varchar(16384)
set @execsql = " select USER_NAME from TBL_USER "
execute (@execsql)
end
create procere zhouxiaobotest2 @qry varchar(16384),@ipage int, @num int,@maxpages int
as
/*@qry SQL語句, @ipage 頁數, @num 每頁記錄條數, @maxpages 最大查詢頁數 */
begin
select USER_NAME from TBL_USER
end
現在我的問題是調用存儲過程zhouxiaobotest,mStatement.execute()始終是false;而調用zhouxiaobotest2 mStatement.execute()就是true,能得到結果集。我想知道如何修改程序使我能夠調用zhouxiaobotest取得結果集(之前調試程序運行沒有拋出任何異常,而且控制台運行存儲過程也都正確)
③ jdbc調用存儲過程為什麼語句不能加分號
如果你在程序裡面寫sql,就不要加分號,在程序裡面編譯器會把分號當做sql本身的一部分,所以會報錯 如果是在查詢工具裡面(比如plsql),這個時候可以加上分號,在工具裡面分號是個分隔符,看到分號就標志著本條sql語句結束了; 當然不加也可以,在工具裡面看不到分號就認為本條sql沒有結束。 比如:你寫了兩條sql,但是沒有用分號隔開,此時,工具會當做一條來執行,只不過會報錯而已。