Com base no que entendi sobre a consistência eventual, todos esses serviços (consumidores) receberão o evento ao mesmo tempo e os processarão separadamente , o que, em um bom cenário, levará à consistência dos dados.
Não, não necessariamente. Como eu comentei, não podemos desfazer um email enviado, por isso ainda precisamos de uma espécie de "sequência". O IPC sobre gerenciamento de dados orientado a eventos não é isento de orquestração 1 .
Por exemplo, o email não deve ser enviado, a menos que as transações anteriores sejam concluídas com êxito e o serviço de email obtenha uma prova disso. 3
No entanto, e se um serviço falhar ao processar o evento? por exemplo, desconexão súbita, erro no banco de dados, etc ... Qual é um bom padrão / prática para lidar com essas falhas de transação?
Diga olá às falácias da computação distribuída . São elas que complicam as coisas e, como sempre, não há balas de prata para lidar com elas.
Antes de iniciar nossa jornada em busca da Arca Perdida, devemos considerar perguntar à organização primeiro. Freqüentemente, a solução está em como a organização enfrenta esses problemas no mundo real .
O que todos (departamentos) fazem quando determinados dados estão ausentes ou incompletos?
Veremos que departamentos diferentes têm soluções diferentes que, no total, compõem a solução a ser implementada.
Enfim, aqui estão algumas práticas que podem nos ajudar com a estratégia a seguir.
Em vez de garantir que o sistema esteja em um estado consistente o tempo todo, podemos aceitar que o sistema o obtenha em algum momento no futuro. Essa abordagem é especialmente útil para operações comerciais de longa duração.
O caminho para o sistema atingir a consistência varia de sistema para sistema. Pode envolver de processos automatizados a algum tipo de intervenção humana. Por exemplo, o típico tentando novamente mais tarde ou o contato com o Atendimento ao Cliente .
Abortar todas as operações
Coloque o sistema novamente em um estado consistente por meio de transações compensatórias . No entanto, temos que levar em conta que essas transações também podem falhar, o que poderia nos levar a um ponto em que a inconsistência é ainda mais difícil de ser resolvida. E, novamente, não podemos desfazer um email enviado.
Para um número baixo de transações, essa abordagem é viável, porque o número de transações compensatórias também é baixo. Se houvesse várias transações comerciais envolvidas no IPC, seria difícil lidar com uma transação compensadora para cada uma delas.
Se optarmos por compensar transações , acharemos o padrão de design do disjuntor muito útil - e obrigatório, ouso dizer -
Transações distribuídas
A idéia é abranger várias transações em uma única transação, por meio de um processo geral de controle conhecido como Gerenciador de Transações . Um algoritmo comum para lidar com transações distribuídas é o commit de duas fases .
A principal preocupação das transações distribuídas é que elas dependem do bloqueio dos recursos durante sua vida útil e, como sabemos, as coisas também podem dar errado para o Transaction Manager .
Se os gerenciadores de transações ficarem comprometidos, podemos acabar com vários bloqueios nos diferentes contextos limitados, resultando em comportamentos inesperados devido ao enfileiramento das mensagens. 2
Decomposição de operações. Por quê?
Se você estiver decompondo um sistema existente e encontrar uma coleção de conceitos que realmente desejam estar dentro de um único limite de transação, talvez deixe-os até o final.
Sam Newman
Na linha dos argumentos acima, Sam - em seu livro Building Microservices - declara que, se realmente não pudermos pagar a consistência eventual, devemos evitar dividir a operação agora.
Se não pudermos dividir certas operações em duas ou mais transações, pode-se dizer que - provavelmente - essas transações pertencem ao mesmo contexto limitado ou, pelo menos, a um contexto transversal que ainda precisa ser modelado.
Por exemplo, no nosso caso, percebemos que as transações 1 e 2 estão intimamente relacionadas entre si e provavelmente ambas podem pertencer ao mesmo contexto limitado Contas , usuários , registro , qualquer que seja ...
Considere colocar as duas operações dentro dos limites da mesma transação. Facilitaria toda a operação. Pesar também o nível de criticidade de cada transação. Provavelmente, se a transação nº 2 falhar, não deverá comprometer toda a operação. Em caso de dúvida pergunte à organização .
1: Não é o tipo de orquestração que você pensa. Não estou falando da orquestração do ESB. Estou falando de fazer com que os serviços reajam ao evento apropriado.
2: Você pode encontrar opiniões interessantes de Sam Newman sobre transações distribuídas.
3: Verifique a resposta de David Parker sobre esse assunto.