クライアントからのリクエストを処理するウェブサーバーがあります。このWebサーバーの1つのコンポーネントは、データベースへの接続を保持します。
使用を開始する前に、接続が閉じられているか、何らかの方法で機能しなくなっているかを認識できる必要があります。現在、私は次のようなことをしています。
// Decide connection details on alias.
private String alias = null;
// I must have my own because I prepare statements.
private Connection connection = null;
public Connection getConnection() {
try {
if ( connection.isClosed() ) {
// Start afresh.
connection = null;
}
// ** More tests here to check connection is ok.
if (connection == null) {
// Make a new connection.
connection = Connections.getConnection(alias);
}
} catch (SQLException ex) {
// Cause a NPE further down the line.
connection = null;
}
return connection;
}
悲しいことに、これは時々、私がさまざまなエラーの1つを受け取るような古い接続を返します。そのようなものの1つは次のようになります。
Java.sql.SQLException:Io例外:ソフトウェアによる接続の中止:ソケット書き込みエラー
これは記録されたエラーの1つにすぎず、約72時間アイドル状態になった後に発生することに注意してください。
私が探しているのは、接続が稼働していて安定しているかどうかを一貫して判断する必要がある、接続の最小限のデータベース汎用テスターです。これは可能ですか?
それに対して非常に小さなクエリを実行してもかまいませんが、データベースに依存せず、時間/リソースをほとんどまたはまったく必要としない必要があります。
ところで:私はJava 5で実行しているのでConnection.isValid
は私にとって解決策ではありません。
追加
後でこの質問にアクセスする方のために-私は最終的に提供されたアドバイスを受け取り、実際の接続プールに移動しました。驚くほど簡単であるだけでなく、私の問題のすべてが消えました。
唯一の奇妙な部分は、接続プールを使用すると、接続が終了したときに接続をclose
する必要があるという認識でした。プールはクローズをインターセプトし、バックグラウンドでプールに戻します。
最良の方法は、Oracleの場合はSELECT 1
またはSELECT 1 FROM DUAL
のような単純なSQLステートメントを実行することです。 (ベンダー固有の構文については、データベースを参照してください。)
失敗した場合は、接続を更新してください。それがJava WebLogicのようなEEアプリサーバーが、そうするように構成した場合にそれらをテストするために行うことです。
試してみてください
Java.sql.Connection.isValid(int timeout)
接続が閉じられておらず、まだ有効である場合はtrueを返します。
すべてのデータベースには、既存のテーブルに依存しないクエリがあります。 Oracleの場合は、
select 1 from dual
他の多くのデータベース(MySQL、H2)については、
select 1
DB2には、独自の構文があります。
values 1
私の場合、Java.sql.Connection.isValid(int timeout)を使用します:
GetConnectionメソッド(またはこの例ではgetInstance no poll)があります:
try {
if (connect == null) || ! connect.isValid() ) {
connect.DriverManager.getConnection(...);
} catch (SQLException e) {
logger.error(...);
connect = null;
}
return connect;