2016-10-11 32 views
0

Oracleプール接続ではoracle.jdbc.pool.OracleDataSourceを使用しますが、接続はデータベース内に存続しているようです。 Oracleデータベースに接続している間今日、私はエラーを得た:SpringのOracleデータソースで接続が破棄されない

ORA-12516:TNS:リスナーは、一致するプロトコルスタック

で利用可能なハンドラを見つけることができなかったと私は、データベース管理者によって言われた、あまりにも多くのこと開いている接続はアプリケーションから「IDLE」モードのままです。

私はojdbc7使用

<dependency> 
    <groupId>com.oracle</groupId> 
    <artifactId>ojdbc7</artifactId> 
    <version>12.1.0.1</version> 
</dependency> 

春applicationContext.xmlをファイル:

<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close"> 
    <property name="URL" value="${jdbc.url}" /> 
    <property name="user" value="${jdbc.username}" /> 
    <property name="password" value="${jdbc.password}" /> 
    <property name="connectionCachingEnabled" value="true" /> 
</bean> 

DBCONNECTクラス:

import java.sql.Connection; 
import java.sql.SQLException; 
import javax.sql.DataSource; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Repository; 

@Repository 
public class DbConnect { 

    @Autowired 
    private DataSource dataSource; 

    public Connection getConnection() throws SQLException { 
     return dataSource.getConnection(); 
    } 
} 

また、私はJDK7のtry-と資源の構文を使用します接続のための私のDAOレベル:

@Autowired 
private DbConnect dbConnect; 

public List<User> getAllUsers() { 
    List<User> list = new ArrayList<>(); 

    try(Connection connection = dbConnect.getConnection()) { 
     try(PreparedStatement preparedStatement = connection.prepareStatement("select * from V_USERS t")) { 
      try(ResultSet resultSet = preparedStatement.executeQuery()) { 
       while(resultSet.next()) { 
        list.add(RowFetcher.fetchUser(resultSet)); 
       } 
      } 
     } 
    } 
    catch(Exception e) { 
     log.error(e.getMessage(), e); 
    } 

    return list; 
} 

実際の問題はどこにあるのかわかりません。 OracleDataSourceではなくc3p0を使用する必要がありますか? ojdbc7にバグがありますか、コードにエラーがありますか?

ありがとうございます!

+1

'DbConnect'のコードを投稿してください。 –

+0

投稿を編集しました。変更内容を確認してください – 0bj3ct

+0

データベースの接続数は適切か、Oracleデータソースのデフォルト設定は何ですか? – KarlP

答えて

1

のために働く.T org.apache.commons.dbcp.BasicDataSource異なるデータソースを使用してみてください。しかし、OracleDataSourceが実際のプールであるか、またはOracleConnectionPoolDataSourceにする必要があるかどうかはわかりません。

プレーンなOracleプールを使用する代わりに、HikariCPを使用することをお勧めします。 configuration optionsのページとデフォルト。

は、その場合には、あなたのデータソースは、

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"> 
    <property name="datasourceClassName" value="oracle.jdbc.pool.OracleDataSource" /> 
    <property name="dataSourceProperties"> 
     <props> 
      <prop key="URL" value="${jdbc.url}" /> 
      <prop key="user" value="${jdbc.username}" /> 
      <prop key="password" value="${jdbc.password}" /> 
      <prop key="connectionCachingEnabled" value="true" /> 
     </props> 
    </property> 
</bean> 

ノートのようになります。プールのサイズにも素敵pageあります(オラクルから実際にあります!)。

コードを整理してDbConnectクラスを削除し、プレーン接続で作業する代わりにJdbcTemplateを挿入(または作成)することをお勧めします。すべてのJDBCオブジェクトの管理を保存します。

private final JdbcTemplate jdbcTemplate; 

@Autowired 
public YourRepository(DataSource ds) { 
    this.jdbcTemplate=new JdbcTemplate(ds); 
} 

public List<User> getAllUsers() { 
    List<User> list = new ArrayList<>(); 
    return this.jdbcTemplate("select * from V_USERS t", new RowMapper() { 
     public User mapRow(ResultSet rs, int row) throws SQLException { 
      return RowFetcher.fetchUser(rs); 
     } 
    }); 
} 
+0

完全な答えをありがとう。とても役に立ちました。私はHikariCPとSpring JdbcTemplateを使用します。 – 0bj3ct

2

データソースの制限プロパティを設定して、キャッシュのサイズを制御できます。

<property name="connectionCacheProperties"> 
    <props> 
    <prop key="MinLimit">${jdbc.limit.min}</prop> 
    <prop key="MaxLimit">${jdbc.limit.max}</prop> 
    <prop key="InitialLimit">${jdbc.limit.init}</prop> 
    </props> 
</property> 
+0

これはおそらく解決策です。 MaxLimitはデフォルト '0'で、無制限です。 – KarlP

0

プールの全体のポイントは、オープン接続を維持することです私

1

Java接続プールであるUniversal Connection Pool(UCP)があります。
詳細な設定の詳細については、UCP with Springを参照してください。

関連する問題