Oracle Advanced Queuing中不相关消息的选择性出列

时间:2010-10-20 03:19:53

标签: oracle advanced-queuing oracle-aq oracle-streams

此问题涉及 Oracle Streams Advanced Queuing 中的消息出列。

我需要确保按顺序处理彼此相关的消息。

例如,假设队列中有四条消息,这四条消息具有一个称为事务引用(txn_ref)的业务相关字段,其中两条消息(1,3)属于同一事务(000001):

id | txn_ref | 
---+---------+
 1 | 000001  |
 2 | 000002  |
 3 | 000001  |
 4 | 000003  |

还假设我正在运行4个希望从此队列中出队的线程/进程。应该发生以下情况:

  1. 线程1使消息#1
  2. 出列
  3. 线程2使消息#2
  4. 出列
  5. 线程3将消息#4排队(因为消息#3与#1相关,而#1尚未完成)。
  6. 线程4阻塞等待消息
  7. 主题1将其工作提交给消息#1
  8. 线程4(或者可能是线程1)使消息#3出列。
  9. 我最初的想法是,我可以通过一个出队条件来实现这一点,其中ENQ_TIME(入队时间)不晚于具有相同TXN_REF的所有消息的任何其他ENQ_TIME。但我的问题是如何引用我尚未选择的消息的TXN_REF,以便选择它。 e.g。

    // Java API
    String condition = "ENQ_TIME = (select min(ENQ_TIME) from AQ_TABLE1 where ??";
    dequeueOption.setCondition(condition);
    

    有可能实现我想要的目标吗?

2 个答案:

答案 0 :(得分:2)

要回答您的直接问题,可以使用专为此目的设计的correlation字段(表中称为CORRID)来实现。

因此,在enqueue上,您将使用AQMessageProperties.setCorrelation()方法将TXN_REF值作为参数。然后,在你的情况下你会做这样的事情:

// Java API
String condition = "tab.ENQ_TIME = (select min(AQ_TABLE1.ENQ_TIME) from AQ_TABLE1 self where tab.CORRID=AQ_TABLE1.CORRID)";
dequeueOption.setCondition(condition);

答案 1 :(得分:1)

如果可能,您可以尝试使用邮件组的策略。 Oracle Documentation简要介绍了它,但我发现this Toad World article更有用。基本上,您设置队列表以将同时提交的所有消息视为一个“组”。出列时,一次只有一个用户可以从一组“消息”中出列。