Oracle 高级队列中不相关消息的选择性出队

发布于 2024-09-28 09:21:40 字数 836 浏览 9 评论 0原文

该问题涉及Oracle Streams Advanced Queueing中的消息出队。

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

例如,假设队列中包含四个消息,这些消息具有称为事务引用 (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);

这里可以实现我想要的吗?

This question refers to the dequeueing of messages in Oracle Streams Advanced Queueing.

I need to ensure that the messages which are related to each other are processed sequentially.

For example, assume the queue is seeded with the four messages that have a business-related field called transaction reference (txn_ref) and two of the messages (1,3) belong to the same transaction (000001):

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

Assume also that I am running 4 threads/processes that wish to dequeue from this queue. The following should occur:

  1. thread 1 dequeues message #1
  2. thread 2 dequeues message #2
  3. thread 3 dequeues message #4 (because message #3 is related to #1 and #1 has not yet completed).
  4. thread 4 blocks waiting for a message
  5. thread 1 commits its work for message #1
  6. thread 4 (or perhaps thread 1) dequeues message #3.

My initial thought was that I could achieve this with a dequeue condition where the ENQ_TIME (enqueue time) is not later than any other ENQ_TIME of all the messages that have the same TXN_REF. But my problem is how to reference the TXN_REF of a message that I have not yet selected, in order to select it. e.g.

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

Is it possible to achieve what I want here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

姜生凉生 2024-10-05 09:21:40

要回答您的直接问题,可以使用专为此目的而设计的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);

To answer your direct question, this can be achieved using the correlation field (called CORRID in the table), which is designed for this purpose.

So, on the enqueue, you'd use the AQMessageProperties.setCorrelation() method with the TXN_REF value as the parameter. Then, in your condition you would do something like this:

// 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);
∞觅青森が 2024-10-05 09:21:40

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

A strategy which you can try, if possible, is using Message Groups. The Oracle Documentation describes it briefly, but I found this Toad World article to be far more useful. Basically, you setup the queue table to treat all messages committed at the same time as one "group". When dequeueing, only one user at a time can dequeue from a "group" of messages.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文