2

这个问题是指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. 线程 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);

有可能在这里实现我想要的吗?

4

2 回答 2

2

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

因此,在入队时,您将使用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);
于 2010-10-25T20:35:39.303 回答
1

如果可能的话,您可以尝试的一种策略是使用消息组。Oracle 文档对其进行了简要描述,但我发现这篇 Toad World 文章更有用。基本上,您设置队列表以将同时提交的所有消息视为一个“组”。出队时,一次只有一个用户可以从“一组”消息中出队。

于 2010-10-26T12:46:32.257 回答