2017-07-06 97 views
1

我有一個關於性能的問題。CallableStatement.close()會導致性能問題

我工作的應用程序是一個Spring MVC應用程序(v3.2.9)。它託管在WebSphere Application Server(v8.5.5)上。它連接到AS400 DB2系統(驅動程序是JTOpen v9.1)。我的應用程序在IBM AS400系統上調用存儲過程。它被稱爲使用Spring的JdbcTemplate.execute方法。下面的代碼:

jdbcTemplate.execute(new CallableStatementCreator() { 
     @Override 
     public CallableStatement createCallableStatement(Connection con) throws SQLException { 
      CallableStatement cs = con.prepareCall("{CALL XXXXXXSP (?, ?)}"); 
      cs.setString(1, xxx); 
      cs.setString(2, xxx); 
      return cs; 
     } 
    }, 
    new CallableStatementCallback<String>() { 
     @Override 
     public String doInCallableStatement(CallableStatement cs)throws SQLException, DataAccessException { 
      cs.execute(); 
      return null; 
     } 
    }); 

我們遇到了一些問題,其中該過程的調用偶爾會引發錯誤「[SQL0501]光標C1不開」調高記錄和審查後,它看起來像這樣的錯誤只有在應用程序嘗試重新使用CallableStatement時纔會發生。相應的遊標在上次使用此CallableStatement時被關閉,導致錯誤(我不是100%確定是否這種重用是預期的行爲)。錯誤發生在每天20次左右,這是一個相對較低的百分比,因爲這個應用程序有更高的流量。

我的問題是,將cs.execute();之後的代碼加入cs.close();會導致代碼性能下降嗎?

+0

問題出在您要在AS400上調用的程序中。你將不得不在AS400上修復它。我在野外看到這些信息時,如果沒有找到記錄,就不會執行close語句,也不會執行承諾控制的初始提交。我也在野外看到沒有檢查打開是否成功,因此抓取失敗。添加代碼以檢查打開的語句。如果公開失敗,則發佈另一個公開聲明。 – danny117

+0

@ danny117感謝您的建議,只是想澄清...您所指的開放語句和關閉語句將在AS400上的程序中,而不是在Java代碼中,是正確的嗎? –

+0

是的,它看起來像as400編碼問題。我假設close是關閉遊標。 – danny117

回答

2

一般來說,您應該調用close()方法來關閉語句,因爲它釋放資源。這沒有任何問題。

但是JdbcTemplate關閉語句適合你,所以不需要它。

這裏是JdbcTemplate的做在執行結束execute(CallableStatementCreator csc, CallableStatementCallback<T> action)方法:

JdbcUtils.closeStatement(cs); 
DataSourceUtils.releaseConnection(con, getDataSource()); 

而且從CallableStatementCallback API:

doInCallableStatement(CallableStatement cs) throws SQLException ,DataAccessException 

獲取由JdbcTemplate.execute調用的活動JDBC 的CallableStatement 。不需要關心關閉語句 或連接,或關於處理事務:這將全部是由Spring的JdbcTemplate處理的 。 注意:任何ResultSets打開應該 在回調實現中的最後塊中關閉。 Spring 將在返回回調後關閉Statement對象,但是此 不一定意味着ResultSet資源將爲 已關閉:Statement對象可能會被連接池合併, 只有關閉調用纔會將對象返回到池但不是 物理關閉資源。

+0

看起來像存儲過程顯式打開的任何結果集需要由客戶端關閉。我不確定應該發生的框架在哪裏。如果結果集不應該返回給調用者,那麼存儲過程應該已經關閉了結果集。另外,由於遊標名稱在作業中必須是唯一的,所以存儲過程對於遊標名稱應該使用比C1更具體的名稱。 – jweberhard

相關問題