使 OracleDataSource 对数据库重启和 hickups 健壮

Make OracleDataSource robust against Database restarts and hickups

所以我得到了一个使用 Connectionfactory 的高级队列:

ConnectionFactory jmsQueueConnectionFactory() throws JMSException, SQLException { 
  final OracleDataSource dataSource = new OracleDataSource();
  dataSource.setUser(username);
  dataSource.setPassword(password);
  dataSource.setURL(url);
  dataSource.setImplicitCachingEnabled(true);
  dataSource.setFastConnectionFailoverEnabled(true);

  return AQjmsFactory.getConnectionFactory(dataSource);
} 

这是共享数据库上的 运行,它可能会重新启动,或者有时网络会出现短暂的故障。这导致队列中不再有消息。

我使用 spring MessageListener 来检索消息,实际上没有任何指示器或队列不再 运行 的任何东西。重新启动应用程序后,我会收到一堆应该已经处理过的旧消息。

是否有重新连接的方式或特定数据源实现?

更新:监听器实现

@Bean
OracleAqQueueFactoryBean etlQueueFactory() throws JMSException, SQLException {
    final OracleAqQueueFactoryBean bean = new OracleAqQueueFactoryBean();
    bean.setConnectionFactory(jmsQueueConnectionFactory());
    bean.setOracleQueueUser("USER");
    bean.setOracleQueueName("QUEUE");
    return bean;
}


@Bean
DefaultMessageListenerContainer jmsContainer() throws JMSException, SQLException {
    final DefaultMessageListenerContainer bean = new DefaultMessageListenerContainer();
    bean.setConnectionFactory(jmsQueueConnectionFactory());
    bean.setDestination(etlQueueFactory().getObject());
    bean.setMessageListener(new MyListener());
    bean.setSessionTransacted(false);
    return bean;
}

public class MyListener implements MessageListener {
    @Override
    public void onMessage(Message message) {
        ...
    }
}

我猜你必须在 JMS 级别而不是数据库级别上执行此操作。

不确定您使用的是哪种类型的侦听器,但是 Spring 中的 DefaultMessageListenerContainer 是通过 consumer.receive(timeout) 循环实现的。它比使用普通侦听器更健壮,因为它将尝试在每个轮询周期重新连接(如果需要)。