2017-07-06 5 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メソッドを使用して呼び出されています。ここでは、コードです:私たちは、ロギングを上げると確認した後、「[SQL0501]カーソルC1が開いていない」は、この手順の呼び出しは時折エラーがスローされますいくつかの問題に実行している

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; 
     } 
    }); 

、それがこのエラーのように見えますアプリケーションがCallableStatementを再利用しようとするときにのみ発生します。このCallableStatementが最後に使用されたときに、それぞれのカーソルが閉じられました。この結果、エラーが発生します(この再利用が予想される動作であるかどうかはわかりません)。このエラーは、1日に20回程度起こります。これは、このアプリケーションのトラフィックが非常に高いため、比較的低いパーセンテージです。

私の質問は、コードにの後にコードにcs.close();を追加すると、コードのパフォーマンスが低下しますか?

+0

問題は、AS400で呼び出すプログラムにあります。あなたはAS400でそれを修正する必要があります。私はレコードが見つからないときにはクローズド・ステートメントが実行されず、コミットメント制御のための初期コミットはされていないので、これらはワイルドで表示されます。私は野生でもオープンが成功したかどうかをチェックしないので、フェッチが失敗することがわかります。開いているステートメントをチェックするコードを追加します。オープンが失敗した場合は、クローズ・ステートメントを発行し、別のオープン・ステートメントを発行します。 – danny117

+0

@ danny117アドバイスをいただきありがとうございます。明確にしたいだけです...あなたが言及しているオープンステートメントとクローズステートメントは、JavaコードではなくAS400のプログラムにあるでしょうか? –

+0

はい、as400コーディングの問題のようです。私は近くにカーソルが近いと仮定しています。 – danny117

答えて

2

一般的にclose()メソッドを呼び出してリソースを解放するので、文を閉じる必要があります。これに問題はありません。

しかし、あなたのためのJdbcTemplateクローズステートメントは必要ありません。

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

そしてCallableStatementCallback APIから:

doInCallableStatement(CallableStatement cs) throws SQLException ,DataAccessException 

がアクティブJDBC たCallableStatementでJdbcTemplate.executeによって呼び出され、ここで

はJdbcTemplateが実行execute(CallableStatementCreator csc, CallableStatementCallback<T> action)メソッドの最後に何をすべきかです。 Statement またはConnectionを閉じること、またはトランザクションを処理することについて気にする必要はありません。これは、すべてSpringのJdbcTemplateによって処理される になります。 注:コールバック実装内のfinallyブロックで をクローズする必要があります。 Spring は、コールバックが返された後でStatementオブジェクトをクローズしますが、この は必ずしもResultSetリソースが であることを意味しません。Statementオブジェクトは接続プールによってプールされる可能性があります。 物理的にリソースを閉じるのではなく、 です。

+0

ストアドプロシージャによって明示的に開かれた結果セットは、クライアントによって閉じられる必要があるようです。私は、起こるはずのフレームワークがどこにあるのかは分かりません。結果セットが呼び出し側に返されないと想定される場合、ストアード・プロシージャーは結果セットをクローズしていなければなりません。また、カーソル名はジョブ内で一意である必要があるため、ストアード・プロシージャーはカーソル名にC1よりも具体的な名前を使用する必要があります。 – jweberhard

関連する問題