使用 oracle aq 和 spring-jms 时选择太多



我们开始使用oracle AQ和spring-jms,它工作得很好。但是当 ~1000 条消息通过我的队列时BUS_BILLING_RECEIVE_QT我在下面写了 110000 个选择:

select /*+ INDEX(TAB AQ$_BUS_BILLING_RECEIVE_QT_I) */ tab.rowid, tab.msgid, tab.corrid, tab.priority, tab.delay, tab.expiration , tab.retry_count, tab.exception_qschema, tab.exception_queue, tab.chain_no, tab.local_order_no, tab.enq_time, tab.time_manager_info, tab.state, tab.enq_tid, tab.step_no, tab.sender_name, tab.sender_address, tab.sender_protocol, tab.dequeue_msgid, tab.user_prop, tab.user_data from "WORKLOAD_PROD"."BUS_BILLING_RECEIVE_QT" tab where q_name = :1 and (state = :2 ) order by q_name, state, enq_time, step_no, chain_no, local_order_no for update skip locked

它会导致性能问题...也许 sombody 知道哪个产生这个选择,以及我如何减少这个巨大的数量?

此语句是 dbms_aq.dequeue 语句后面的内部 SQL 语句,当dequeue_mode(dequeue_options_t类型的字段)为 LOCK 或 REMOVE (不是 BROWSE 或 REMOVE_NODATA) 时。

要减少数量,您必须减少排队的频率。

请参阅 https://erikwramner.wordpress.com/2016/06/08/oracle-aq-jms-performance,关于接收超时的部分。简而言之,当消息到达时,Oracle 会唤醒所有等待会话,并且它们都将发出相同的选择。只有一个会成功,但这非常昂贵。我们已经向Oracle报告了它,但他们不想修复它(通过唤醒一个线程,在Java中比较通知和通知)。

请参阅 https://jira.spring.io/browse/SPR-14225,特别是我在 Spring 中提交的修复请求。我们目前的解决方案是子类化 DefaultMessageListenerContainer,使用 receiveNoWait 进行轮询,并在 Java 中短暂休眠。这大大减少了数据库的负载。或者,您可以减少听众的数量,但通常这不是一个选项!

最新更新