2016-11-29 11 views
0

JSF JavaアプリケーションでdbcpのBasicDataSourceを使用しています。基本的な慣例は、使用後に接続を閉じることです。私はcatchで行います。最後に私のコードで行います。私は私の接続を閉じないことを決定するのでただし、アプリケーションは、エラーで停止し接続プーリング:接続を閉じるかどうかを確認する

java.sql.SQLException: Connection is null. 
at org.apache.tomcat.dbcp.dbcp2.DelegatingConnection.checkOpen(DelegatingConnection.java:611) 
at org.apache.tomcat.dbcp.dbcp2.DelegatingConnection.createStatement(DelegatingConnection.java:258) 

を磨きます。私のコードはほとんど大丈夫動作しますが、その後、多くの場合、このエラーで停止:以下

Caused by: org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections 

は私の接続構成である:

public class StageDB { 
    public StageDB() {} 
    public static Connection getConnection() { 
     BasicDataSource ds = new BasicDataSource(); 
     ds.setDriverClassName(JDBC_DRIVER); 
     ds.setUsername(USER); 
     ds.setPassword(PASS); 
     ds.setUrl(DB_URL); 
     ds.setTimeBetweenEvictionRunsMillis(20*1000); 
     ds.setMinIdle(0); 
     ds.setMaxIdle(10); 
     ds.setMaxOpenPreparedStatements(100); 
     conn = ds.getConnection(); 
     return conn; 
    } 
} 

私は、これらの設定で遊んで、また、使用してみたことに言及すべきですデフォルトと同じですが、同じ結果が得られます。私は何が間違っていますか?

+3

'ds.close()'とは何ですか?データソースを作成してすぐに閉じますか? – Kayaman

+0

これはdbcpのバグのようです。はい、必要がなくなったらconn.close()を呼び出すべきです。バックエンドがOracleの場合は、OracleのUCPを試してみましたか? –

+0

@ Kayaman、コードはDAOによって使用されるデータソースクラスにあります。 conn(ds.getConnection()を参照)を返します。 –

答えて

0

私はそれがすべて間違っていることを認識した後、私はこれに対する解決策を見つけました。それでは、私が思いついたのは、私のデザインアプローチと完全に一致するものです。

//1. Create pooled connections datasource class using the Singleton. 

/*************************** 
* This is the pooled datasource class 
****************************/ 
public class PrimaryDS { 
    private PrimaryDS primaryDS; 

    public PrimaryDS() { 
     ds = new BasicDataSource(); 
     ds.setDriverClassName(JDBC_DRIVER); 
     ds.setUsername(USER); 
     ds.setPassword(PASS); 
     ds.setUrl(DB_URL); 
    } 

    public static PrimaryDS getInstance() { 
     primaryDS = primaryDS == null ? new PrimaryDS() : primaryDS; 
     return primaryDS; 
    } 

    public BasicDataSource getDataSource() { 
     return ds; 
    } 

    public void setDataSource(BasicDataSource ds) { 
     this.ds = ds; 
    } 
} 

//2. DAOs make call to the datasource. Initialize DS in the DAO's constructor. 

/*************************** 
* This is in the DAO's constructor 
****************************/ 
ds = PrimaryDS.getInstance().getDataSource(); 

//3. DAOs have the database manupulation methods. In each of these methods, 
//create connection object from ds, and ensure it's closed in the catch - finally. 

/*************************** 
* This is inside one of the DAO methods 
****************************/ 
try { 
    conn = ds.getConnection(); 
    stmt = null; 
    rs = null; 
    PreparedStatement pstmt = conn.prepareStatement(ACTIVE_ACCOUNTS_SQL); 
    pstmt.setByte(1,status); 
    ResultSet rs = pstmt.executeQuery(); 
    // TODO loop through rs 
} catch (SQLException e) { 
    e.printStackTrace(); 
} finally { 
    try { 
     if(rs != null) rs.close(); 
     if(stmt != null) stmt.close(); 
     if(conn != null) conn.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
関連する問題