2

接続プールを実装する方法がある場合は、私の接続プールを見てもらえますか?

public class ConnectionPool {
    private static List<DBConnection> pool = null;
    private static int available = 0;
    private ConnectionPool() {}

    public static DBConnection getConnection() {
        if (pool == null) {
             pool = new ArrayList<DBConnection>();
             for (int i = 0; i < 3; i++) {
                 try {
                    pool.add(new DBConnection());
                    available++;
                } catch (SQLException e) {
                    e.printStackTrace();
                }
             }
        }
        if (pool.size() > 0) {
            available--;
            return pool.remove(available);
        } else {
            return null;
        }
    }

    public static void returnConnection(DBConnection c) {
        pool.add(c);
        available++;
    }
}

私は 1 つの配列のみを使用しており、クライアントは接続プールに接続を要求し、それを使用してから接続プールに返す必要があります。

  Connection connection = ConnectionPool.getConnection();
  connection.execute("insert into users values('"+user.getUsername()+"', '"+user.getPassword()+"', '"+user.getGroup()+"', '"+banned+"', '"+broker+admin+sharehodler+company+"')");      
  ConnectionPool.returnConnection(connection);
  connection = null;

この実装に関するフィードバックが必要です。ありがとうございました

4

5 に答える 5

6

この実装を非常に問題にするポイントがいくつかあります。

  • スレッドセーフ。複数のスレッドがプールで動作する場合はどうなりますか? 読み取り/書き込みアクセスでリストをロックしていません。
  • 静的な最大プール サイズは 3 接続です。必要かどうかに関係なく、すべての接続をすぐに作成できます。一般的な戦略は、許可された/構成された最大数に達するまで、一連の接続を作成し、必要に応じてさらに作成することです。
  • 静的メソッドしかありません。複数のプールを持つことができるはずです。つまり、のインスタンスが必要ですConnectionPool
  • 作成された接続にホスト+データベース名+ユーザー+パスワードを渡す方法はありません。
  • 「壊れた」接続には対処しません。既存の接続が失敗した場合は、接続を再作成する必要がある場合があります。これは、私がプールを使い始める前に思っていたよりもはるかに重要です。
  • 静的な値の代わりに設定値を使用してください。ポイント 2 を参照してください
  • 最後に: もちろん、これを自分で作成するのは興味深いことですが、プロジェクトにプールが必要な場合は、c3p0tomcat 接続プールなどの既存のプールを選択してください。

指摘することはもっとあると思いますが、これらが修正されない限り、続行しても意味がありません。

于 2012-05-10T09:00:13.380 に答える
5

プールの実装に関する大きな問題の 1 つは、ネイキッド接続をプールの呼び出し元に渡すことです。これは、誰かがプールから接続を取得して閉じ、プールに戻すことができることを意味します。これはまずい

この問題を回避する通常の方法は、委譲を使用して返される接続オブジェクトをラップし、close メソッドへの呼び出しを無視するようにすることです (または、さらに良い方法として、close() で基礎となる接続を安全にプールに返すようにします)。

その他の主要な問題:

  • トランザクションの途中で接続が返された場合はどうなりますか?
  • 接続が何らかの理由で破損または切断された場合はどうなりますか? プールに残りますか?

全体として、独自の接続プール実装を作成するのではなく、既存の接続プール実装を再利用する必要があります。最近では、多くのタイプ 4 ドライバーに独自の接続プールが含まれています。

于 2012-05-10T09:08:18.537 に答える
3

いくつかの考え:

  • あなたのコードはスレッドセーフではありません。多分これに取り組みます。
  • getConnection() のコードが多すぎます。遅延初期化は本当に必要ですか?
  • available は役に立たず、pool.size() で代用できます。
于 2012-05-10T08:53:19.607 に答える
2

私の知る限り、

  • オブジェクトのみを取得するには、getConnection()メソッドを変更する必要があります。Connection

    接続の準備とプーリングは getConnection() メソッドから取り除かれ、ConnectionPoolクラスが初めてロードされるときに追加される必要があります。

    また、すべてのシナリオで機能させるにはconnection timeout、などの他の属性を処理する必要があります。purging

    スレッドセーフにもします。

于 2012-05-10T09:02:26.467 に答える