8

私は常にシングルスレッド環境のJavaSEでJDBCを使用していました。しかし、今は接続プールを使用して、多くのスレッドがデータベース(MSSQLおよびOracle)と対話できるようにする必要があり、APIの基本的な理解が不足しているように見えるため、接続プールを作成するのに苦労しています。

接続してログに記録した後のAFAIKConnectionは、データベースへの物理的なtcp/ip接続を表します。これはStatement、を介したデータベースとのSQLインタラクションと見なすことができる(s)を作成しますConnection

  • トランザクションとロールバックはどこで発生しますか?ConnectionまたはStatementレベルですか。
  • 'one'ConnectionがN個のステートメントを作成し、それを異なるスレッドに渡して、それぞれがその使用を所有できるようにするのは安全Statementですか?

そうでない場合、およびプールを構成した後、次のようになります。

OracleDataSource ods = new OracleDataSource(); 
ods.setURL("jdbc:oracle:thin:@tnsentryname");
ods.setUser("u");
ods.setPassword("p");
  • ところで、接続プールのサイズはどこで設定できますか?

  • これは、接続を正しく使用するために各スレッドで行うことですか?

//theadrunメソッド

Connection conn = ods.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("the sql");
// do what I need to do with rs
rs.close();
int updateStatus = stmt.executeUpdate("the update");
stmt.close();
conn.close();

//スレッド実行メソッドの終了

  • プールの物理的な接続が何らかの理由でクラッシュまたは切断された場合、プールは自動的に再接続を試み、プールに新しい接続を挿入して、後続のpool.getConnection()が正常な接続を取得するようにしますか?

どうもありがとう、私の悪い英語を許してください。

4

7 に答える 7

7

接続プールは、独自のラッパー実装で Connection および Statement インスタンスを装飾します。接続で close を呼び出すと、実際にはそれをプールに解放するだけです。準備されたステートメントで close を呼び出すと、実際にはそれを接続のステートメント キャッシュに解放するだけです。ステートメントを準備するときは、接続からキャッシュされたステートメント インスタンスをフェッチするだけかもしれません。これらはすべて非表示になっているため、心配する必要はありません。

クライアントに接続が与えられると、その接続が解放されてプールに戻されるまで、他のクライアントはその接続を使用できなくなります。通常、必要なときに接続を取得し、終了したらすぐに接続を返します。接続はプールで開いたままになっているため、接続の取得と解放のオーバーヘッドはほとんどありません。

単一の JBDC 接続と同じようにプールからの接続を使用し、リソースのクローズに関するベスト プラクティスに従って、接続やステートメントがリークしないようにする必要があります。他の回答のいくつかで、try/catch/finally の例を参照してください。

プールは、接続リソースを管理し、それらをクライアントに渡す前にテストして、それらが古くなっていないことを確認できます。また、プールは必要に応じて接続を作成および破棄します。

于 2009-08-13T15:02:39.547 に答える
3
  1. トランザクションは接続レベルで発生します。

  2. いいえ。通常、JDBC ドライバーは、別のステートメントがアクティブな間、同じ接続で 2 番目のステートメントを実行できないようにします。

接続プーリングが必要な場合は、DBCP フレームワークを試してください。これはかなりまともな障害処理を提供します (失効した接続や、クライアント コードによって返されていない接続に気付くなど)。

あなたのコードに関して:常にコードをラップしますtry{...}finally{...}

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
     conn = ds.getConnection ();
     stmt = ...
     rs = ...
}
finally {
     rs = close (rs);
     stmt = close (stmt);
     conn = close (conn);
}

public static Connection close (Connection conn) {
    if (conn != null) {
        try {
            conn.close ();
        }
        catch (SQLException e) {
            e.printStackTrace(); // Log, don't rethrow!!
        }
    }
    return null;
}

このコードは、すべての接続などが常に正しく閉じられ、閉じている間の例外によって以前のエラーが隠されないようにします。

于 2009-08-13T14:53:19.053 に答える
2

接続プーリングに関するSun のチュートリアルから始めるべきだと思います。これに加えて、接続プーリングの多くの実装があり、Apache からのものを含むいくつかのオープンソースがあります。ここで車輪を再発明するのではなく、本当にそこから始めるべきです。

于 2009-08-13T15:02:10.780 に答える
1

特定の接続で 1 つのステートメントのみを開いておくことができます。接続プールを使用して複数の接続を作成することはそれほど難しくありませんが、より多く使用されているものの 1 つを使用する方法があります。

また、標準の JDBC を使用する場合は、Statement よりも PreparedStatement を使用することをお勧めします。

私は iBatis を使ってきましたが、箱から出してすぐに使えるのはとてもいいです。他にもいくつかのものをテーブルにもたらします。

于 2009-08-13T15:04:44.003 に答える
0

これを見てください(+:

于 2009-08-13T15:27:43.927 に答える
0

余分なビット:

  1. アプリケーションサーバーは接続プーリングを提供する傾向があり、非常に巧妙になります。アプリサーバーを使用している場合は、独自のものを追加する前に、すぐに使えるものを注意深く調べてください。

  2. 取引:お持ちの場合

    取引開始

    get connection work close connection // プールに戻ることを意味する

    get connection (同じ分離レベルなど)
    // 同じ接続を取得します。プールはトランザクション用にそれを予約します

    work // 同じトランザクション クローズ接続で発生

    コミットトランザクション // すべての作業をコミットします

  3. 接続とエラー

プールの実装は賢い場合があります。プールからのいずれかの接続で、DB サーバーがバウンスしたことを示す特定のエラーが発生した場合、プールはすべてのプール メンバーを破棄することを選択できます。

于 2009-08-13T15:33:28.987 に答える