2

我从正在侦听 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
4

2 回答 2

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

于 2013-11-13T15:48:10.227 回答
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 似乎不适用于此设置。但是以秒为单位设置一个相当短的时间应该可以解决问题。

于 2013-11-13T01:44:09.213 回答