Получение устаревшего соединения с использованием OracleDataSource с драйвером OCI - PullRequest
4 голосов
/ 11 мая 2011

Я получаю устаревшую ошибку соединения, когда в течение нескольких часов нет запросов к базе данных из моего java-приложения.

Это простое Java-приложение, запущенное на Linux с OCI (драйвер типа). Не спрашивайте меня, почему OCI, почему не худой. Я использую OracleDataSource и OracleConnectionCacheManager для поддержки кэша объектов подключения. Вот фрагмент кода:

import java.sql.Connection; 
import java.sql.SQLException; 
import java.util.Properties; 

import oracle.jdbc.pool.OracleConnectionCacheManager; 
import oracle.jdbc.pool.OracleDataSource; 

import org.apache.log4j.Logger; 

import com.exception.DataException; 

public class ConnectionManager { 
private static OracleDataSource poolDataSource = null; 
private final static String CACHE_NAME = "CONNECTION_POOL_CACHE"; 
private static OracleConnectionCacheManager occm = null; 

public static void init(String url,String userId,String password) throws PCTDataException{ 
Properties cacheProps = null; 
try { 
poolDataSource = new OracleDataSource(); 
poolDataSource.setURL(url); 
poolDataSource.setUser(userId); 
poolDataSource.setPassword(password); 

cacheProps = new Properties(); 
cacheProps.setProperty("MinLimit", "1"); 
cacheProps.setProperty("MaxLimit", "5"); 
cacheProps.setProperty("InitialLimit", "1"); 
cacheProps.setProperty("ValidateConnection", "true"); 

poolDataSource.setConnectionCachingEnabled(true); 
occm = OracleConnectionCacheManager.getConnectionCacheManagerInstance(); 
occm.createCache(CACHE_NAME, poolDataSource, cacheProps); 
occm.enableCache(CACHE_NAME); 
} catch (SQLException se) { 
throw new DataException("SQL Exception while initializing connection pool"); 
}catch(Exception e){ 
throw new DataException("Exception while initializing connection pool"); 
} 
} 

public static Connection getConnection() throws PCTDataException { 
try{ 
if (poolDataSource == null) { 
throw new SQLException("OracleDataSource is null."); 
} 
occm.refreshCache(CACHE_NAME, OracleConnectionCacheManager.REFRESH_INVALID_CONNECTIONS); 
Connection connection = poolDataSource.getConnection(); 
return connection; 
}catch(SQLException se){ 
se.printStackTrace(); 
throw new DataException("Exception while getting Connection object"); 
}catch(Exception e){ 
e.printStackTrace(); 
throw new DataException("Exception while getting Connection object"); 
} 
} 

public static void closePooledConnections() { 
try{ 
if (poolDataSource != null) { 
poolDataSource.close(); 
} 
}catch(SQLException se){ 
}catch(Exception e){ 
} 

} 
} 

Ошибка выглядит следующим образом:

ConnectionManager.java:getConnection:87 - Exception while getting Connection object: 
java.sql.SQLException: Invalid or Stale Connection found in the Connection Cache 
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112) 
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146) 
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208) 
at oracle.jdbc.pool.OracleImplicitConnectionCache.getConnection(OracleImplicitConnectionCache.java:390) 
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:404) 
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:189) 

Чего мне не хватает?

Ответы [ 3 ]

1 голос
/ 17 апреля 2012

Вместо использования OracleDataSource + OracleConnectionCacheManager я бы рекомендовал использовать OracleOCIConnectionPool, который был специально разработан для кэширования соединений OCI.

Это замена замены OracleDataSource, за исключением того, что свойства PoolConfig для OracleDataSource и OracleOCIConnectionPool немного отличаются.

1 голос
/ 11 мая 2011

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

0 голосов
/ 17 сентября 2014

Вы получите сообщение об ошибке «Неверное или устаревшее соединение», если у вас есть соединение в пуле соединений, которое больше не подключено к базе данных.Ниже приведено несколько сценариев, которые могут привести к этому

  1. Соединение прервано вручную из базы данных с помощью dba.Например, если соединение было прервано с использованием «ALTER SYSTEM KILL SESSION»
  2. Когда соединение существует в пуле соединений без длительного использования и отключено из-за тайм-аутов, установленных базой данных (idle_time)
  3. Перезапуск базы данных
  4. Сетевое событие вызвало разрыв соединения, возможно, из-за того, что сеть стала недоступной или брандмауэр отбросил соединение, которое было открыто слишком долго.

Запустите приведенный ниже запрос, чтобы определить IDLE_TIME, применяемый базой данных

select * from dba_profiles dp, dba_users du
where dp.profile = du.profile and du.username ='YOUR_JDBC_USER_NAME';

Теперь попробуйте следующую конфигурацию

Properties cacheProps = new Properties(); 
cacheProps.setProperty("MinLimit", "0"); 
cacheProps.setProperty("MaxLimit", "5"); 
cacheProps.setProperty("InitialLimit", "1"); 
cacheProps.setProperty("ValidateConnection", "true");
cacheProps.setProperty("InactivityTimeout", "17000"); //something lower than the DB IDLE_TIME
cacheProps.setProperty("PropertyCheckInterval", "16000") /*something lower than the inactivity timeout
 - to make sure that connections which were inactive for more than InactivityTimeout
 are always removed from the pool*/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...