【问题标题】:What is causing this JMS error connecting to OracleAQ?是什么导致连接到 OracleAQ 时出现此 JMS 错误?
【发布时间】:2013-11-14 21:23:48
【问题描述】:

我从正在侦听 OracleAQ 的 java 服务收到零星错误。

这似乎每天晚上都在发生,我无法确定发生了什么。难道真的是数据库连接问题?

或者“出队失败”是否表明它已连接并且发生了其他事情?

以下是例外:

[2013-11-04 18:16:16,508] WARN  org.springframework.jms.listener.DefaultMessageListenerContainer - Setup of JMS message listener invoker failed for destination 'MYCOMPANY_INFO_QUEUE' - trying to recover. Cause: JMS-120: Dequeue failed; nested exception is java.sql.SQLException: Io exception: Socket read timed out
oracle.jms.AQjmsException: JMS-120: Dequeue failed
       at oracle.jms.AQjmsError.throwEx(AQjmsError.java:311)
       at oracle.jms.AQjmsConsumer.dequeue(AQjmsConsumer.java:2234)
       at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:1028)
       at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:951)
       at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:929)
       at oracle.jms.AQjmsConsumer.receive(AQjmsConsumer.java:781)
       at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:430)
       at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:310)
       at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
       at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1096)
       at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1088)
       at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:985)
       at java.lang.Thread.run(Thread.java:662)

[Linked-exception]
java.sql.SQLException: Io exception: Socket read timed out
       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:255)
       at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:976)
       at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1168)
       at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285)
       at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3329)
       at oracle.jms.AQjmsConsumer.dequeue(AQjmsConsumer.java:1732)
       at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:1028)
       at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:951)
       at oracle.jms.AQjmsConsumer.receiveFromAQ(AQjmsConsumer.java:929)
       at oracle.jms.AQjmsConsumer.receive(AQjmsConsumer.java:781)
       at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:430)
       at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:310)
       at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
       at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1096)
       at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1088)
       at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:985)
       at java.lang.Thread.run(Thread.java:662)

[2013-11-04 18:16:16,569] INFO  org.springframework.jms.listener.DefaultMessageListenerContainer - Successfully refreshed JMS Connection

【问题讨论】:

  • Java 和数据库之间是否有任何可能在一段时间后断开连接的情况,例如防火墙?如果它们在同一台服务器上,则不太可能,但这是以前出现的长期连接神秘断开的原因。

标签: java queue jms spring-jms oracle-aq


【解决方案1】:

jms 接收超时应以秒为单位进行配置(而 db 超时以毫秒为单位)。因此,请确保您的 jms 值较小。例如,这是我的工作弹簧配置:

<bean id="xxxJmsTemplate" class="org.springframework.jms.core.JmsTemplate102">
    <property name="connectionFactory" ref="xxxJmsConnectionFactory"/>
    <property name="defaultDestinationName" value="some_queue"/>

    <property name="receiveTimeout" value="10"/><!-- seconds -->

</bean>

PS:特殊的 Spring 常量 RECEIVE_TIMEOUT_NO_WAIT 值 -1 似乎不适用于此设置。但是以秒为单位设置一个相当短的时间应该可以解决问题。

【讨论】:

  • “过分热心的整洁怪胎”是版主,您之前的回答是deleted because it was not answer,至少达到了其中两个标准。我知道您还没有enough reputation to comment,但是发布应该是评论的内容作为解决问题的答案是不允许的。
  • 嗯,我的帖子中有有用的信息,所以我认为删除它是愚蠢的,不管“政策”如何。事实证明,我原来的帖子有一个线索——JMS 接收超时设置是问题,至少在我的情况下是这样。
【解决方案2】:

我建议查看等待时间的出队选项。

import oracle.AQ.AQDequeueOption;
...
AQDequeueOption options = null;
options = new AQDequeueOption();
options.setWaitTime(AQDequeue.WAIT_NONE);
//WAIT_NONE = do not wait if messages are not available
//WAIT_FOREVER = waits "forever"; default value
...

WAIT_FOREVER 设置是默认设置,将等待队列中的消息可用;但是,这会使数据库连接保持打开状态。 我相信这就是您“偶尔”遇到错误的原因;大多数时候消息都在排队并顺利运行;然后当消息没有排队(每晚)时,您的数据库连接就会超时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 2010-11-12
    • 2020-12-24
    • 1970-01-01
    相关资源
    最近更新 更多