dequeue selettiva di messaggi non correlati in Oracle Advanced Queuing
-
09-10-2019 - |
Domanda
Questa domanda si riferisce alla dequeueing di messaggi in Oracle Streams Advanced Queuing .
I necessità di garantire che i messaggi che sono collegati tra loro vengono elaborati sequenzialmente.
Per esempio, assumere la coda è seminato con i quattro messaggi che hanno un campo connessi alle imprese denominato riferimento transazione (txn_ref) e due dei messaggi (1,3) appartengono alla stessa operazione (000001):
id | txn_ref |
---+---------+
1 | 000001 |
2 | 000002 |
3 | 000001 |
4 | 000003 |
Si supponga anche che io sono in esecuzione 4 thread / processi che desiderano annullare l'accodamento da questa coda. dovrebbe verificarsi:
- Thread 1 Ritiri dalla coda dei messaggi # 1
- filo 2 Ritiri dalla coda dei messaggi # 2
- filo 3 Ritiri dalla coda dei messaggi # 4 (a causa messaggio # 3 è legato alla # 1 e # 1 non ha ancora completato).
- filo 4 blocchi in attesa di un messaggio
- filo 1 impegna il suo lavoro per il messaggio # 1
- filo 4 (o forse thread 1) Ritiri dalla coda messaggio # 3.
Il mio primo pensiero è stato che ho potuto raggiungere questo obiettivo con una condizione in cui il dequeue ENQ_TIME (tempo di accodamento) non è tardi rispetto a qualsiasi altro ENQ_TIME di tutti i messaggi che hanno lo stesso TXN_REF. Ma il mio problema è come fare riferimento al TXN_REF di un messaggio che non ho ancora scelto, al fine di selezionarla. per es.
// Java API
String condition = "ENQ_TIME = (select min(ENQ_TIME) from AQ_TABLE1 where ??";
dequeueOption.setCondition(condition);
E 'possibile ottenere ciò che voglio qui?
Soluzione
Per rispondere alla tua domanda diretta, questo può essere realizzato utilizzando il campo correlation
(chiamato CORRID
in tabella), che è stato progettato per questo scopo.
Quindi, sulla enqueue, devi usare il metodo AQMessageProperties.setCorrelation()
con il valore TXN_REF come parametro. Poi, nella sua condizione si farebbe qualcosa di simile:
// 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);
Altri suggerimenti
Una strategia che si può provare, se possibile, sta utilizzando gruppo Messaggio. Il Oracle documentazione descrive brevemente, ma ho trovato questo rospo mondiale articolo di essere molto più utile. In sostanza, si imposta la tabella di coda per il trattamento di tutti i messaggi commessi al tempo stesso come una "gruppo". Quando dequeueing, un solo utente alla volta può dequeue da un "gruppo" di messaggi.