Um fluxo de mensagens pode ser considerado para consistir nas partes constituintes a seguir:
A seqüência de eventos de quando um fluxo processa uma mensagem pode ser considerada como sendo:
Observe que esta seqüência de eventos não faz distinção entre o acesso de tabelas e a gravação de mensagens de saída. Embora um fluxo geralmente seja conhecido por produzir algum tipo de mensagem de saída, não há distinção real entre ele e a atualização de uma tabela de banco de dados. Em ambos os casos, há alguma alteração no estado dos dados no sistema.
=====x=========x===x=======x=============x====x===== 1 2 3 4 5 6
A linha representa os dados no sistema ao longo do tempo. No tempo 1, uma mensagem chega e é extraída da fila de entrada. Nos tempos 2, 3, 4 e 5, as tabelas de banco de dados são atualizadas ou as filas recebem gravações. Essas alterações de estado são indicadas pelo símbolo x. Finalmente, no tempo 6 as mensagens de saída partem e o sistema é submetido ao quiesce. Entre esses eventos, não há alteração no estado dos dados e isso é indicado pelo símbolo =.
Agora, deixe-nos considerar os efeitos das falhas no sistema. Se ocorrer uma falha (por exemplo, o plug tiver sido removido da máquina na qual o intermediário está sendo executado), as alterações no estado das tabelas e nas filas feitas antes da falha terão acontecido, mas aquelas que ocorreram depois não terão acontecido. É muito provável que essa situação seja inaceitável (por exemplo, um pagamento de minha conta atual para a minha conta de hipoteca foi extraída da tabela de conta atual, mas não incluída na tabela de conta da hipoteca).
=====x=========x===x=======x=============x====x===== 1 2 3 4 5 6
A linha representa os dados extras no sistema ao longo do tempo. No tempo 1, uma mensagem chega e é extraída da fila de entrada. Antes disso, não há dados extras no sistema e isso é indicado pelo símbolo -. Após esse tempo, o estado representa o fato de que uma mensagem foi extraída da fila de modo que, se necessário, possa ser recuperada. Nos tempos 2, 3, 4 e 5, as tabelas de banco de dados são atualizadas ou as filas recebem gravações. Novamente, o estado dos dados extras são alterados de modo que as alterações nas tabelas e nas filas possam ser desfeitas, se necessário. Finalmente, no tempo 6 as mensagens de saída partem, o sistema é submetido ao quiesce e não há dados extras no sistema mais uma vez. Entre esses eventos, não há alteração no estado dos dados extra e isso é indicado pelo símbolo =. Se ocorrer uma falha em qualquer tempo entre 1 e 6, os dados extras serão utilizados para restaurar o estado original dos dados do sistema de modo que, na verdade, nenhuma das filas de saída tenha recebido gravação, nenhuma das tabelas tenha sido alterada e a mensagem de entrada não tenha sido extraída da fila de entrada. Se não ocorrer nenhuma falha, as alterações ficarão permanentes no tempo 6, ou seja, uma operação desfazer após uma falha subseqüente não surtirá efeito.
Esse modo de operação é conhecido como modo de transação coordenada. A conclusão bem-sucedida de uma transação é conhecida como sua confirmação. A conclusão malsucedida é conhecida como rollback. (Consulte a seção XYZ para uma descrição longa e complexa de como se alcançar isso; lembre-se de que esse não é o padrão e que nem todos os bancos de dados ou sistemas em fila suportam isso.)
O recurso-chave do modo de transação coordenada da operação é que todas as alterações nas filas e tabelas associadas a uma mensagem de entrada são efetuadas ou nenhuma é efetuada independentemente de onde ou quando as falhas ocorrem e essa é sua vantagem chave. No entanto, isso não se adequa a todas as situações. Dois exemplos simples de tais situações são:
MAIN -----x=========x===x=======x=============x====x----- 1 2 4 5 8 9 1o. AUX --------------x======x========x------ 3 6 7
A linha superior representa a transação principal conforme anteriormente. A transação é um termo especialmente abstrato, mas o que se iguala a ela no mundo real são os dados extras necessários para restaurar o estado original caso seja preciso. A linha inferior representa uma transação auxiliar. No tempo 3, é feita uma atualização a uma tabela (ou fila). Uma outra é feita no tempo 6. No tempo 7, o fluxo decide se todas as alterações que precisam ser efetuadas sob a transação auxiliar estão concluídas e confirma as alterações.
Se o fluxo falhar antes do tempo 7, o estado do sistema seria inalterado porque ambas as transações seriam revertidas. Se ocorrer uma falha após o tempo 7, mas antes do tempo 9, a transação auxiliar seria confirmada (ela já foi), mas a principal seria revertida. Se uma falha não tiver ocorrido pelo tempo 9, não haverá falha e ambas as transações serão confirmadas.
Você não está restrito a uma única transação auxiliar e a apenas confirmá-las. Inúmeras atualizações podem ser feitas nas tabelas de banco de dados e elas podem ser confirmadas ou revertidas. Em seguida, você pode fazer algumas alterações adicionais às mesmas tabelas de banco de dados, ou a tabelas diferentes e, em seguida, confirmar ou reverter essas alterações.
Cada banco de dados que você utilizar possui sua própria transação auxiliar e, portanto, se o fluxo atualizar tabelas pertencentes a diferentes instâncias do banco de dados (ou seja, diferentes nomes de origem de dados) haverá uma transação auxiliar por banco de dados. Isso pode (e de fato deve) ser confirmado ou revertido individualmente. Quaisquer atualizações que não tenham sido confirmadas ou revertidas quando a operação for concluída (tempo 9) serão automaticamente confirmadas ou revertidas pelo intermediário de acordo com o êxito ou falha do processamento (ou seja, se uma exceção atingir o nó input, ou não).
Observe que alguns tipos de bancos de dados, como DB2 no AIX, não permitem transações coordenadas ou não coordenadas na mesma instância de banco de dados. Nesses casos, devem ser criadas instâncias de banco de dados separadas. Você deve configurar uma instância de banco de dados para as transações coordenadas e outra para as transações não coordenadas.
As transações de banco de dados auxiliares são confirmadas ou revertidas utilizando as instruções ESQL COMMIT e ROLLBACK. As operações fora da transação principal são obtidas especificando-se UNCOORDINATED nas instruções individuais de banco de dados utilizadas, como as instruções INSERT e UPDATE.
Nem todos os sistemas de enfileiramento possuem a capacidade dos bancos de dados descritos acima. No caso do MQ, cada leitura ou gravação não coordenada individual em uma fila possui uma confirmação implícita. Portanto, você não pode colocar duas mensagens e, em seguida, decidir confirmá-las ou revertê-las. Essa é uma limitação do sistema subjacente que o WebSphere Message Broker não pode ocultar. Portanto, as instruções COMMIT e ROLLBACK operam apenas nos bancos de dados.
A descrição acima trata-se apenas dos fluxos e não menciona os nós. A forma como um fluxo está dividido em nós é, em princípio, de nenhuma relevância para uma discussão sobre as transações. Qualquer número de nós pode fazer atualizações nas transações principais e em qualquer número de transações auxiliares de qualquer maneira que considerem adequado sem restrição. O que importa é o que você faz e não como o faz. Na prática, no entanto, isso é válido apenas para operações em bancos de dados simplesmente porque outras origens de dados (VSAM, Queues) possuem recursos mais limitados.
Um caso especial válido a ser mencionado é quando todas as atualizações de bancos de dados forem feitas dentro das transações auxiliares. Nesse caso, o atributo "Transação Coordenada" do fluxo de mensagens pode ser configurado como "não". Isso faz com que todas as referências de tabela fora da transação principal salvem o problema de ter que especificá-la em cada operação do banco de dados. Também pode tornar os fluxos mais rápidos.