使用 OracleDataSource 和 OCI 驱动程序获取陈旧连接

发布于 2024-11-07 01:50:33 字数 3076 浏览 0 评论 0原文

当我的 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) 

我缺少什么?

I am getting stale connection error when there is no requests to the database from my java application for couple of hours.

Its a simple java application runned on Linux box with OCI (type driver). Dont ask me why OCI, why not thin. I am using OracleDataSource and OracleConnectionCacheManager for maintaining the cache of connection objects. Here is the code snippet:

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){ 
} 

} 
} 

The error is as follows:

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) 

What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

养猫人 2024-11-14 01:50:33

也许您需要设置保持活动?它的作用是周期性地,当不使用时,它会向数据库服务器发送一个 ping 信号,基本上表明我还在这里,不要将我拒之门外。不过,尝试调试并不是那么有趣。问题可能是数据库服务器上的设置存在最大连接期限或终止空闲连接的时间。您的池中也可能有一些设置,您可以使用它们来检查这一点,然后告诉它在发生这种情况时获取新的设置。我希望我能提供更多帮助,但我没有与甲骨文合作过。

Maybe you need to set keep alives on? what this does is periodically, when not in use it send a ping to the database server basically saying I am still here and don't close me out. This is not that fun to try to debug though. The problem could be a setting on your database server where there is a max connection age, or a time to kill idle connections. There also could be some settings in your pool that you could use to that would check for this and then just tell it to get a new one when this happens. I wish I could be more help but I have not worked with oracle.

烂人 2024-11-14 01:50:33

我建议使用 OracleOCIConnectionPool,而不是使用 OracleDataSource + OracleConnectionCacheManager,它是专门为缓存 OCI 连接而设计的。

它是 OracleDataSource 的替代品,只是 OracleDataSource 和 OracleOCIConnectionPool 的 PoolConfig 属性略有不同。

Instead of using OracleDataSource + OracleConnectionCacheManager, I would recommend using the OracleOCIConnectionPool, which was specifically designed for caching OCI connections.

It is a drop in replacement for OracleDataSource, except the PoolConfig properties for OracleDataSource and the OracleOCIConnectionPool are a bit different.

逆流 2024-11-14 01:50:33

当连接池中有一个连接不再主动连接到数据库时,您将收到“无效或过时的连接”错误。以下是可能导致

  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*/

You will get the "Invalid or Stale Connection" error when you have a connection in the connection pool which is no longer connected to the Database actively. Below are few scenarios which can lead to this

  1. Connection is manually aborted from the database by a dba. For example, if
    the connection was killed using "ALTER SYSTEM KILL SESSION"
  2. When a connection exists in the connection pool without being used for a
    long time and is disconnected due to the timeouts enforced by the
    database (idle_time)
  3. A database restart
  4. A network event has caused
    the connection to drop, probably because the network has become
    unavailable or a firewall has dropped a connection which has been
    open for too long.

Run the below query to determine the IDLE_TIME enforced by the Database

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

Now try with the below configuration

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*/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文