2016-10-11 3 views
0

Я использую oracle.jdbc.pool.OracleDataSource для соединений Oracle Pooling, но кажется, что соединения остаются в базе данных. Сегодня я получил сообщение об ошибке при подключении к базе данных Oracle:Источник oracle datasource не разрушает соединение

ORA-12516: TNS: слушатель не смог найти доступный обработчик с стеком протоколов согласования

И мне сказали нашему администратор базы данных, слишком много открытые соединения остаются в режиме «IDLE» из моего приложения.

Я использую ojdbc7:

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

Spring 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> 

Класс БДСВЯЗЬ:

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 примерочных с-ресурсами синтаксиса мой уровень 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; 
} 

Невозможно выяснить, в чем проблема. Должен ли я использовать c3p0 вместо OracleDataSource? Есть ли ошибка в ojdbc7 или ошибка в моем коде?

Заранее благодарен!

+1

Вы должны отправить код для 'DbConnect' –

+0

Я отредактировал сообщение.см. изменения – 0bj3ct

+0

Сколько подключений подходит вашему dba, и каковы настройки по умолчанию в источнике данных Oracle. – KarlP

ответ

1

Всей точка бассейна держать открытые соединения. Однако я не уверен, что 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 на бассейн проклейки (который на самом деле от Oracle!).

Я бы также предложил очистить код, чтобы удалить класс 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

Попробуйте использовать другой источник данных org.apache.commons.dbcp.BasicDataSource .t работает для меня

1

У нас есть универсальный пул соединений (UCP), который является пулом соединений Java.
Дополнительную информацию о конфигурации см. В UCP with Spring.