4

PGPoolingDataSourceクラスを使用してデータベースプールを作成すると問題が発生します。しばらくすると、多くのユーザーが作業しているときにプールがダウンし、エラーが表示されません。

プールを作成するクラスのコードは次のとおりです。

public class PgConexion {
    private static PgConexion _instancia = new PgConexion(); // instancia de la clase
    private Configuracion config;
    private PGPoolingDataSource source;

    /**
     * instancia la clase y carga las opciones de configuracion
     */
    public PgConexion() {
        final URL archivo = Constantes.RUTA_CONFIG;

        if(archivo != null){
            config = new Configuracion(archivo);
        }
    }

    /**
     * regresa la instancia del pool de conexiones
     * @return
     */
    public static PgConexion getInstance() {
        return _instancia;
    }

    /**
     * crear la conexion la conexion
     * @return
     * @throws SQLException
     */
    public void crearConexion() throws SQLException{
        source = new PGPoolingDataSource(); 

        // configuracion del pool
        source.setDataSourceName("Logistica");
        source.setServerName(config.get("servidor_sql"));
        source.setPortNumber(Integer.parseInt(config.get("puerto_sql")));
        source.setDatabaseName(config.get("bd_sql"));
        source.setUser(config.get("usuario_sql"));
        source.setPassword(config.get("contrasena_sql"));
        source.setMaxConnections(30);
    }

    /**
     * devuelve la conecion a utilizar
     * @return
     * @throws SQLException
     */
    public Connection nuevaConexion() throws SQLException{
        if(source == null){
            crearConexion();
        }

        // genero la conexion de la lista del pool
        return source.getConnection();
    }

    /**
     * Cierra las conexiones y libera los recursos
     */
    public void cerrarConexion(){
        source.close();
    }
}

これを修正するにはどうすればよいですか?

4

2 に答える 2

10

JDBCのドキュメントで説明されているように、 PGPoolingDataSourceを使用することはあまり良い考えではありません。

基本的な問題は、接続の制限に達したときに接続が閉じられるまで、getConnection()の呼び出しがブロックされることです。

同時接続の最大量として値30を設定したため、31番目を開く場合は、呼び出しを行うスレッドでブロックが発生します。

可能な解決策:

  • 同時接続の実際の上限が確実な場合は、maxConnectionsを増やします。postgresql.confでサーバー側の接続制限も確認する必要があります。
  • PGSimpleDataSourceを使用します。アプリケーションのタイプによっては、接続のプールを使用しない(したがって、毎回接続を作成する)ことは問題になりません。
  • 本当に接続プールが必要な場合は、Javaレベルで独自の接続プールを実装するだけです。

編集:以下を実行するだけで、開いている接続の量を確認できます。

SELECT * FROM pg_stat_activity

各行は接続です(pgAdminおよびクエリアナライザからの行を含む)。接続数が上限まで上がらないことが確実な場合(ただし、上がらない場合)、何らかの接続リークの問題が発生している可能性があります。

于 2012-11-03T00:35:57.867 に答える
0

私の経験が関係している場合、問題はおそらくここにあるのではなく、クライアントが何らかの理由で常に接続を閉じているわけではなく、エラー処理のシナリオでそうすることを忘れていることがよくあります。

これに対処する最善の方法は、シナリオによって異なります。クライアントがあなた自身のコードである場合、それは、クライアントが未知の組織の未知の人によって書かれたコードである場合とは大きく異なります。

于 2012-11-03T00:44:11.223 に答える