4

Javaアプリケーションからデータベースへのリクエストが数時間ない場合、古い接続エラーが発生します。

その単純なJavaアプリケーションは、OCI(タイプドライバ)を使用してLinuxボックスで実行されます。なぜ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) 

私は何が欠けていますか?

4

3 に答える 3

1

OracleDataSource + OracleConnectionCacheManager を使用する代わりに、OCI 接続をキャッシュするために特別に設計された OracleOCIConnectionPool を使用することをお勧めします。

OracleDataSource の PoolConfig プロパティと OracleOCIConnectionPool が少し異なることを除いて、これは OracleDataSource の代替品です。

于 2012-04-17T19:15:19.157 に答える
1

たぶん、キープアライブをオンにする必要がありますか?これが行うことは定期的で、使用されていないときはデータベース サーバーに ping を送信し、基本的に私はまだここにいて、私を閉じないことを伝えます。ただし、デバッグを試みるのはそれほど楽しいことではありません。問題は、最大接続期間があるデータベース サーバーの設定、またはアイドル状態の接続を強制終了する時間である可能性があります。プールには、これをチェックして、これが発生したときに新しいものを取得するように指示するために使用できる設定がいくつかある場合もあります。もっと役に立ちたいと思っていますが、オラクルを扱ったことはありません。

于 2011-05-11T14:53:11.533 に答える
0

データベースにアクティブに接続されていない接続プールに接続がある場合、「無効または古い接続」エラーが発生します。以下は、これにつながる可能性のあるいくつかのシナリオです

  1. データベース管理者がデータベースから手動で接続を中止しました。たとえば、「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*/
于 2014-09-17T19:10:11.800 に答える