导致此JMS错误连接到OracleAQ的原因是什么?

时间:2013-11-05 23:48:32

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

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

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

或者“Dequeue failed”是否表明它已经连接并且发生了其他事情?

以下是例外情况:

[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

2 个答案:

答案 0 :(得分:2)

应该以秒为单位配置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似乎不适用于此设置。但是在几秒钟内设置合理的短时间应该可以解决问题。

答案 1 :(得分: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设置是默认设置,将等待队列中的消息可用;但是这会保持数据库连接打开。 我相信这就是你“零星地”经历错误的原因;大部分时间信息都被排队并顺利运行;然后当消息没有排队(每晚)时,你的数据库连接就会超时。