2010-06-29 3 views
0

Это сообщение предназначено быть меньше вопроса и более, подтверждение, что я делаю все правильно. Я видел много подобных сообщений, но я не уверен, что полностью понимаю все, что было сказано.Java Oracle Пулы соединений - Closed Исключение соединения

Проблема заключается в том, что после определенного количества времени, я получаю исключение при попытке установить соединение с моей базой данных оракула. (Я использую Tomcat 6.0 и Spring)

Ранее я имел следующую конфигурацию:

private PoolDataSource poolDataSource = null; 

public MainDAOImpl(String url, String username, String password) 
     throws Exception 
{ 
    poolDataSource = PoolDataSourceFactory.getPoolDataSource(); 

    try 
    { 
     poolDataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); 
     poolDataSource.setURL(url); 
     poolDataSource.setUser(username); 
     poolDataSource.setPassword(password); 
    } 
    catch(SQLException e) 
    { 
     ... 
    } 
} 

public List<Object> getValues(String query) 
{ 
    Connection connection = null; 
    PreparedStatement preparedStatement = null; 

    try 
    { 
     connection = poolDataSource.getConnection(); 
     preparedStatement = connection.prepareStatement(query); 

     ... 
    } 
    catch(SQLException e) 
    { 
     ... 
    } 
    finally 
    { 
     //close connections 
    } 
} 

Однако иногда preparedStatement = connection.prepareStatement(query); бросил SQLException с сообщением "Закрыто Exception".

Важно отметить, что конструктор MainDAOImpl ныряет вызывается только один раз в перезапуске сервера (это зависимость нагнетаемого с помощью Spring).

Я недавно изменил мою установку следующим образом:

private DataSource dataSource = null; 

public MainDAOImpl() 
     throws Exception 
{ 
    try 
    { 
     Context initContext = new InitialContext(); 
     Context envContext = (Context)initContext.lookup("java:/comp/env"); 
     dataSource = (DataSource)envContext.lookup("jdbc/myOracleConn"); 
    } 
    catch(NamingException e) 
    { 
     ... 
    } 
} 

и poolDataSource.getConnection() к dataSource.getConnection().

Я также добавил следующий ресурс в моем контексте в Tomcat:

<Resource name="jdbc/myOracleConn" auth="Container" 
      type="javax.sql.DataSource" 
      driverClassName="oracle.jdbc.OracleDriver" 
      url="<myURL>" 
      username="<myUsername>" password="<myPassword>" 
      maxActive="20" maxIdle="10" maxWaith="-1" /> 

Это в основном следует http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html слово за словом.

Все, кажется, работает. Мой вопрос в том, изменят ли эти изменения мою проблему с закрытыми соединениями или что-то другое мне нужно сделать?

Спасибо,

B.J.

ответ

1

Прежде всего, если вы используете Spring для инъекций зависимостей, я рекомендую вам использовать DI впрыснуть зависимости дао в в него.

Другими словами, у вашего DAO должен быть введенный в него DataSource, а не реализация DAO, зная, 1) какой тип DataSource построить или 2) как и где искать его в JNDI. Весна can handle JNDI lookups для вас.

Я также рекомендую использовать в Spring JdbcTemplate, как это делает для большой обертки над сырым JDBC вызывает себя.

Наконец, фактическое исключение вы получаете может быть просто потому, что сервер базы данных закрытия давно открытых соединений. Не уверен, какую реализацию пула подключений вы используете, но в commons-dbcp есть an option for a "validationQuery", который будет запущен пулом, прежде чем возвращать соединение, чтобы проверить, что соединение по-прежнему действует. Я уверен, что большинство других пулов предоставляют аналогичные функции, которые я бы рекомендовал здесь - таким образом ваш DAO никогда не будет получать устаревшие соединения из пула.

Смежные вопросы