Un flusso di messaggio può essere formato dalle seguenti parti:
Una sequenza tipica di eventi relativa al momento in il flusso di messaggio elabora un messaggio è riportata di seguito:
Questa sequenza di eventi non distingue accesso alle tabelle e scrittura di messaggi di output. Sebbene un flusso spesso produca una sorta di messaggio di input, non vi è alcuna distinzione reale tra la produzione di un messaggio di output e l'aggiornamento di una tabella database; in entrambi i casi, lo stato dei dati nel sistema cambia.
=====x=========x===x=======x=============x====x===== 1 2 3 4 5 6
La linea rappresenta i dati nel sistema con il passare del tempo. Nel momento 1, arriva un messaggio che viene acquisito dalla coda di input. Nei momenti 2, 3, 4 e 5, i dati vengono utilizzati per aggiornare le tabelle database o vengono scritti nelle code. Le modifiche nello stato dei dati vengono indicate nel diagramma dal simbolo x. Al momento 6, i messaggi di output vengono inviati e il sistema è inattivo. Tra tali eventi, non vi è alcuna modifica allo stato dei dati; ciò viene indicato nel diagramma dal simbolo =.
Se si verifica un errore sul sistema (ad esempio , una perdita di alimentazione al computer su cui il broker è in esecuzione) vengono applicate soltanto le modifiche allo stato delle tabelle e delle code apportate prima dell'errore. Tale situazione è inaccettabile in determinate circostanze; ad esempio, se si verifica un errore del sistema durante l'esecuzione di un pagamento da un conto corrente a un conto di ipoteca, è possibile che il pagamento venga effettuato dal conto corrente ma che non venga aggiunto all'account di ipoteca.
-----x=========x===x=======x=============x====x----- 1 2 3 4 5 6
La linea nel diagramma rappresenta i dati extra nel sistema con il passare del tempo. Nel momento 1, arriva un messaggio che viene acquisito dalla coda di input. Prima del momento 1, non vi è alcun dato supplementare nel sistema: ciò viene indicato nel diagramma dal simbolo -. Dopo il momento 1, lo stato rappresenta l'acquisizione di un messaggio dalla coda in modo che sia possibile reinserire tale messaggio nella coda, se necessario. Nei momenti 2, 3, 4 e 5, i dati vengono utilizzati per aggiornare le tabelle database o vengono scritti nelle code. Nuovamente, lo stato dei dati supplementari cambia in modo che le modifiche a tabelle e code possano essere annullate, se necessario. Al momento 6, i messaggi di output vengono inviati, il sistema è inattivo e non vi sono dati supplementari nel sistema, ancora una volta. Tra tali eventi, non vi è alcuna modifica allo stato dei dati supplementari e ciò viene indicato dal simbolo =. Se si verifica un errore in qualsiasi momento tra 1 e 6, i dati supplementari vengono utilizzati per ripristinare lo stato originale dei dati del sistema, quindi in effetti, nessun dato è stato scritto nelle code di output, nessuna delle tabelle è stata aggiornata e il messaggio di input non è stato acquisito dalla coda di input. Se non si verifica alcun errore, le modifiche diventano permanenti al momento 6 (un'operazione di annullamento successiva a un errore verificatosi in seguito non annulla le modifiche).
La modalità di operazione descritta in precedenza è nota come modalità di transazione coordinata. Il completamento corretto di una transazione è noto come relativo commit. Il completamento non completato correttamente è noto come rollback.
La funzione chiave della modalità di transazione coordinata di un'operazione prevede che, indipendentemente dal percorso o dal momento in cui si verifica l'errore, tutte le modifiche a code e tabelle, associate a un messaggio di input, vengono applicate o non ne viene applicata alcuna. Tuttavia, tale funzionalità non sempre è adeguata, come illustrano i seguenti esempi:
MAIN -----x=========x===x=======x=============x====x----- 1 2 4 5 8 9 1st AUX --------------x======x========x------ 3 6 7
La linea MAIN rappresenta la transazione principale, che include i dati supplementari necessari per ripristinare lo stato originale, se necessario. La linea 1st AUX rappresenta una transazione ausiliaria. Al momento 3, viene eseguito un aggiornamento a una tabella o a una coda e un altro aggiornamento viene eseguito al momento 6. Al momento 7 il flusso di messaggi determina che tutte le modifiche da eseguire nella transazione ausiliaria sono complete ed esegue il commit di tali modifiche.
Se si fosse verificato un errore nel flusso di messaggi prima del momento 7, lo stato del sistema sarebbe rimasto invariato, perché sarebbe stato eseguito il rollback di entrambe le transazioni. Se si verifica un errore dopo il momento 7 ma prima del momento 9, la transazione ausiliaria sarebbe già stata sottoposta a commit, ma la transizione principale sarebbe stata sottoposta a rollback. Se non si è verificato alcun errore prima del momento 9, entrambe le transazioni vengono sottoposte a commit.
È possibile utilizzare più transazioni ausiliarie ed apportare diversi aggiornamenti alle tabelle database che è possibile sottoporre a commit o a rollback. È quindi possibile apportare ulteriori modifiche alle stesse tabelle database o a tabelle differenti e quindi eseguire il commit o il rollback di tali modifiche.
Ogni database utilizzato dispone della propria transazione ausiliaria, quindi se il flusso di messaggi aggiorna delle tabelle che appartengono a differenti istanze database (differenti nomi di origine dati), esiste una transazione ausiliaria per ogni database. Occorre eseguire il commit o il rollback di tali transazioni singolarmente. Qualsiasi aggiornamento non sottoposto a commit o a rollback al completamento dell'operazione (al momento 9, nel precedente esempio) viene sottoposto a commit o a rollback automaticamente dal broker, in base alla riuscita o meno dell'elaborazione.
Alcuni tipi di databases, tra cui DB2 su AIX, non consentono sia transazioni coordinate che non coordinate nella stessa istanza database. In tali casi, è necessario creare istanze database separate. Configurare un'istanza database per transazioni coordinate e configurare l'altra istanza per transazioni non coordinate.
Utilizzare le istruzioni ESQL COMMIT e ROLLBACK per eseguire il commit e il rollback di transazioni database ausiliarie. Acquisire le operazioni esternamente alla transazione principale specificando la parola chiave UNCOORDINATED nelle singole istruzioni database (ad esempio, le istruzioni INSERT e UPDATE).
Non tutti i sistemi di accodamento dispongono della funzione database descritta precedentemente. Nel caso di WebSphere MQ, ogni singola operazione non coordinata di lettura o scrittura in una coda dispone di un'azione di commit implicata, quindi non è possibile inserire due messaggi e quindi decidere di eseguire il commit o il rollback di entrambi. Le istruzioni COMMIT e ROLLBACK operano quindi soltanto sui database.
La suddetta descrizione presenta dei flussi di messaggi ma non dei nodi. Il modo in cui un flusso di messaggi viene diviso in nodi non ha alcun effetto sulle transazioni. Per operazioni sui database, qualsiasi numero di nodi può eseguire degli aggiornamenti alla transazione principale e su qualsiasi numero di transazioni ausiliarie, senza restrizione.
Una volta eseguiti tutti gli aggiornamenti database nelle transazioni ausiliarie, impostare l'attributo Transazione coordinata del flusso di messaggi su no per influenzare tutti i riferimenti alla tabella esternamente alla transazione principale. Ciò significa che non è necessario specificare l'attributo su ogni operazione database.