2010-10-20 41 views
2

此问题涉及中的消息出队Oracle Streams Advanced QueuingOracle Advanced Queuing中无关消息的选择性出队

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

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

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

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

  1. 线程1出队消息#1
  2. 螺纹2出队消息#2
  3. 螺纹3出列4(因为消息#3是与#1和#1消息#具有不尚未完成)。
  4. 螺纹4块等待消息
  5. 线程1提交其用于消息#工件1
  6. 螺纹4(或者线程1)从队列中取出的消息#3。

我最初的想法是,我可以出队的条件,其中ENQ_TIME(排队等待时间)不大于所有具有相同TXN_REF消息的任何其他ENQ_TIME后实现这一目标。但我的问题是如何引用我还没有选择的消息的TXN_REF,以便选择它。例如

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

是否有可能实现我想要的?

回答

2

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

因此,在入队时,您将使用以TXN_REF值为参数的AQMessageProperties.setCorrelation()方法。然后,在你的病情,你会做这样的事情:

// 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); 
+0

我想要做的是将一条消息出队,除非相关标识符与当前正由另一个工作人员处理的消息匹配。如果我可以识别当前正在处理的相关ID,那么我可以将条件设​​置为corrid而不是{a,b ... z}。 – Synesso 2010-10-26 02:08:24

+0

那么也许你需要两个队列:一个用于上面的消息本身,另一个用作“头部”消息(每个TXN_REF 1个)。一个线程首先将头部出队以获取TXN_REF/CORRID,然后该线程将使用该CORRID处理所有记录。 – 2010-10-26 12:29:31

+0

有趣的想法。标题消息队列就像一个标记系统。入队过程应该仅将队列消息排队*如果队列中不存在队列消息*。 (这是可能的,我想知道)。然后,因为我想每个事务处理不超过1条消息,所以出队过程可以使用头来有选择地从消息队列中出队*单个*消息。当它处理了该消息时,如果还有其他相关消息需要处理,它会将头部消息放回到队列中。复杂,但有一些承诺。 – Synesso 2010-10-29 01:38:37

1

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

+0

这是有前途的,但仍不完全。我的消息在逻辑上是相关的,但它们不会在同一个事务中排队。我仍然可以使用消息组吗? – Synesso 2010-10-29 01:23:22

+0

我几乎肯定他们必须成为同一交易的一部分。 – 2010-10-29 01:45:39