3

BasicDataSource の使用方法に関連するいくつかのバグを修正しました。その一部は理解していますが、まだ回答されていない質問がいくつかあります:)

問題: データベースの障害の後、アプリケーションがデータベースに自動接続できませんでした。

アプリケーションは、Oracle db への JDBC 接続用の TCP 接続プールとしてorg.apache.commons.dbcp.BasicDataSource クラスを使用しています。

修正: いくつかの調査の結果、BasicDataSource で testOnBorrow と testOnreturn が設定されていないことがわかりました。接続をテストするための検証クエリを提供しました。これで問題が解決しました

プール内の接続の最大数が 1 に設定されました

私の理解: 接続プールは接続をアプリケーションに引き渡します。私が考えていたのは、データベースがクラッシュしたときにアプリケーションが魔法のように悪いコレクションをプールに返したことです。プールは接続が正しくないかどうかわからないため、次に必要になったときに同じ接続をアプリケーションに引き渡すため、アプリケーションはデータベースに自動再接続しません。

さて、修正後..接続プールに不良接続が返されるたびに、上記で行った修正のために破棄され、再度使用されることはありません。

これで、アプリケーションに与える前に BasicDataSource が接続をラップすることがわかりました。これにより、アプリケーションが con.close ..BasicDataSource と言うたびに、接続がもう使用されていないことがわかります..プールに接続を返すか、接続を処理します。破棄など

未回答の質問: しかし、私が理解していないのは、アプリケーションが壊れたときに魔法のように接続を接続プールに返す理由です[接続が正常に終了しない場合、con.closeメソッドは呼び出されないことに注意してください] BasicDataSource が接続が閉じられたこと、または ? があることを知る方法はありません。誰かがそのためのコードを教えてもらえますか?

私の全体的な理解は、修正が機能した理由につながりますか??

4

2 に答える 2

4

これは古いスレッドのようなものですが、Google の検索結果で上位に表示されるので、簡単に回答できると思います。BasicDataSource の構成の詳細については、DBCP 構成ページを参照してください: http://commons.apache.org/proper/commons-dbcp/configuration.html

「BasicDataSource は、接続が放棄され、接続プールに戻す必要があることをどのように認識しますか?」という「未回答」の質問に答えるには、次のようにします。(言い換え)...

org.apache.commons.dbcp.BasicDataSource は、Connection のラッパー クラスを使用して、提供する接続のトラフィックと使用状況を監視できます。接続または接続から作成されたステートメントでメソッドを呼び出すたびに、実際には、インターフェイスを実装するか、同じメソッドで基本クラスを拡張するラッパー クラスを呼び出しています (ポリモーフィズム万歳!)。これらのカスタム メソッドにより、DataSource は Connection がアクティブかどうかを知ることができます。

BasicDataSource 自体には、「removeAbandoned」と呼ばれるプロパティと「removeAbandonedTimeout」と呼ばれる別のプロパティがあり、放棄された接続を接続プールに返すこの動作を構成するために使用されます。

「removeAbandoned」は、放棄された接続をプールに戻すかどうかを示すブール値です。デフォルトは「false」です。

「removeAbandonedTimeout」は int であり、接続が放棄されたと見なされる前に経過できる非アクティブの秒数を表します。デフォルト値は 300 (約 5 分) です。

于 2013-11-07T18:55:25.150 に答える
0

放棄された接続のテストを見ると、新しい接続が要求されたときにプール内のすべての接続が「使用中」の場合、「使用中」の接続は放棄についてテストされているようです (最後に使用された時間のタイムスタンプを維持します)。 .

BasicDataSource#setRemoveAbandoned(boolean)およびBasicDataSource#setRemoveAbandonedTimeout(int)を参照してください。

放棄された接続を閉じる際に接続プールがどれほど巧妙であるかどうかに関係なく、各接続が finally ブロックで閉じられていることを常に確認する必要があります。次に例を示します。

Connection conn = getConnection();
try {
    ... // perform work
} finally {
    conn.close();
}

または、 Apache DBUtilsなどの他の手段を使用します。

于 2011-02-01T20:32:47.320 に答える