2010-10-20 27 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