当连接变坏时,有没有办法让JBoss连接池重新连接到Oracle?

时间:2008-09-24 17:30:40

标签: oracle jboss connection-pooling reconnect

我们将JBoss和Oracle放在不同的服务器上。这些连接似乎被丢弃并导致JBoss出现问题。如果连接不好,我怎样才能让JBoss重新连接到Oracle,同时我们找出为什么首先删除连接?

6 个答案:

答案 0 :(得分:32)

虽然你可以使用旧的“select one from dual”技巧,但这样做的缺点是每次从池中借用连接时都会发出额外的查询。对于大批量,这是浪费。

JBoss提供了一个特殊的连接验证器,应该用于Oracle:

<valid-connection-checker-class-name>
    org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
</valid-connection-checker-class-name>

这使用Oracle JDBC Connection类上的专有ping()方法,并使用驱动程序的底层网络代码来确定连接是否仍然存在。

但是,每次借用连接时运行它仍然是浪费的,因此您可能希望使用后台线程检查池中连接的工具,并静默地丢弃死亡连接。这样效率更高,但意味着如果连接失效,那么在后台线程运行其检查之前尝试使用它们将失败。

请参阅wiki docs了解如何配置后台检查(查找background-validation-millis)。

答案 1 :(得分:26)

池上通常有一个配置选项,可以在借用时执行验证查询。如果验证查询成功执行,则池将返回该连接。如果查询未成功执行,则池将创建新连接。

JBoss Wiki记录了池的各种属性。

<check-valid-connection-sql>select 1 from dual</check-valid-connection-sql>

似乎应该这样做。

答案 2 :(得分:9)

评论的代表不够,所以它是一种答案形式。尽管连接检查确实提供了抽象级别,但'Select 1 from dual'和skaffman的org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker方法是等效的。我们不得不反编译oracle jdbc驱动程序以进行故障排除练习,Oracle的内部ping实现是执行'Select 'x' from dual'。 Natch。

答案 3 :(得分:6)

JBoss提供了2种验证连接的方法: - 基于Ping的AND - 基于查询

您可以根据要求使用。这是根据数据源配置文件中定义的持续时间由单独的线程调度的。

<background-validation>true</background-validation> <background-validation-minutes>1</background-validation-minutes>

如果您在Jboss没有正确的oracle驱动程序,有时候可能会出现classcast或相关错误,并且该连接可能会从连接池开始丢失。您可以尝试通过实现org.jboss.resource.adapter.jdbc.ValidConnectionChecker接口来创建自己的ConnectionValidator类。此接口仅提供单个方法“isValidConnection()”并期望“NULL”以换取有效连接。

例如:

public class OracleValidConnectionChecker implements ValidConnectionChecker, Serializable {

   private Method ping;

   // The timeout (apparently the timeout is ignored?)
   private static Object[] params = new Object[] { new Integer(5000) };

   public SQLException isValidConnection(Connection c) {

       try {
           Integer status = (Integer) ping.invoke(c, params);

           if (status.intValue() < 0) {
               return new SQLException("pingDatabase failed status=" + status);
           }

       }
       catch (Exception e) {
           log.warn("Unexpected error in pingDatabase", e);
       }

       // OK
       return null;
   }
}

答案 4 :(得分:3)

我们最近有一些浮动请求处理失败,这些失败是由孤立的oracle DBMS_LOCK会话锁引起的,这些会话锁无限期地保留在客户端连接池中。

所以这是一个解决方案,会在30分钟内强制会话到期,但不会影响应用程序的操作:

<check-valid-connection-sql>select case when 30/60/24 > sysdate-LOGON_TIME then 1 else 1/0 end 
from V$SESSION where AUDSID = userenv('SESSIONID')</check-valid-connection-sql>

这可能涉及从池中获取连接的过程中的一些减慢。确保在负载下进行测试。

答案 5 :(得分:2)

对@skaffman的回答稍作更新。在JBoss 7中,您必须在设置有效的连接检查程序时使用“class-name”属性,并且包装也不同:

<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker" />