5

org.apache.commons.dbcp.BasicDataSourceからのデータベース接続がソケット書き込みエラーで停止している状況が発生しています。

com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset by peer: socket write error

もちろん、その後の接続への書き込みはすべて失敗します。

com.microsoft.sqlserver.jdbc.SQLServerException: The connection is closed.

このような例外をキャッチし、発生時に新しい接続を要求するようにコードを更新した後、再び失敗しました。呼び出しDataSource#getConnection()が呼び出されるたびに実際に新しい接続を提供していないのではないかと疑うのは正しいですか?閉じている既存の接続を再利用するだけではありませんか?

私が正しければ、古い接続を破棄して新しい接続を要求する正しい方法は何ですか?

編集:これが私が知りたいことのより簡潔なバージョンです:

Connection c1, c2;
c1 = DatabaseManager.getConnection();
// c1.close() not called
c2 = DatabaseManager.getConnection(); 

「c1==c2」は本当のステートメントですか?または、2つの接続が割り当てられていますか?後者の場合、次のようなコードは「接続プールのリーク」を表します。

Connection c1;
c1 = DatabaseManager.getConnection();
// c1.close() not called
c1 = DatabaseManager.getConnection();
4

2 に答える 2

11

プールされた接続はDBによって閉じられました。それは2つのことを意味する可能性があります:

  1. 接続プールは、接続を開いたままにしておく時間が長すぎます。
  2. DBは、時間が短すぎると接続を閉じます。

理論的には、タイムアウトを調整するために両側のタイムアウトを増減すると、問題が解決するはずです。

DBCPでは、最善の策は、testOnBorrow=truevalidationQuery設定で戻る前に接続を検証することSELECT 1です。構成オプションは、TomcatJDBCデータソースのドキュメントにあります。


更新に従って更新します。

これが私が知りたいことのより簡潔なバージョンです:

Connection c1, c2;
c1 = DatabaseManager.getConnection();
// c1.close() not called
c2 = DatabaseManager.getConnection(); 

「c1==c2」は本当のステートメントですか?または、2つの接続が割り当てられていますか?

これは2つの異なる接続です。電話をかけた場合にのみ、同じ接続を返すc1.close()妥当な可能性があります。c2

後者の場合、次のようなコードは「接続プールのリーク」を表します。

Connection c1;
c1 = DatabaseManager.getConnection();
// c1.close() not called
c1 = DatabaseManager.getConnection();

はい、プールに戻されることはないため、間違いなく最初の接続がリークされます。ブロック内の可能な限り短いスコープ内のすべてのDBリソースを常に閉じる必要がありtry-finallyます。ただし、少しまともな接続プールは、放棄された接続を取得するように構成できますが、これを「回避策」として使用しないでください。

于 2011-09-08T15:46:02.453 に答える
1

私も同じ問題に直面していました。それから私は問題を引き起こしている複数の非同期ajax呼び出しを行っていることに気づきました。

通話をシリアル化したところ、問題が修正されました。

于 2017-04-25T18:59:50.080 に答える