Padrão Saga #1: O que é?

Bianca Cristina
5 min readJun 1, 2022

If you’d like, you can read this article in English here

Lá atrás quando a vida era mais simples e só existiam monolitos, era mais fácil garantir a consistência de dados, uma vez que podíamos usufruir de transações ACID.

💡 Atomicidade, Consistência, Isolamento e Durabilidade (ACID) são propriedades que garantem consistência dos dados em uma base

Contudo, com o surgimento dos microsserviços, garantir a consistência de dados entre transações que afetam múltiplos serviços e distintas bases de dados é desafiador e é aqui que o padrão Saga se torna útil.

Podemos entender sagas como um conjunto de fluxos de negócio que manipulam dados em múltiplos serviços. Cada saga corresponde a uma sequência de transações locais executadas no contexto de um único serviço e essa sequência é coordenada via mensageria.

Quê? Fluxos de negócio? Serviços? Transações locais? 😰

Calma, vem comigo que vou te explicar melhor!

Padrão Saga

Imagine que voltamos no tempo, especificamente para o ano de 2009, e o trânsito urbano ainda depende de táxis. Um dia, alguém teve uma ideia brilhante: por que não simplificar a vida do passageiro e do motorista com um aplicativo? Dessa ideia, nasceu um aplicativo com várias funcionalidades bacanas…

E se o passageiro pudesse solicitar uma viagem e encontrar o motorista que está mais próximo?

Que tal possibilitar que o pagamento seja efetuado usando uma carteira virtual?

Será que recompensar o usuário não aumentaria a quantidade de viagens solicitadas?

Comparando com o conceito de sagas, podemos entender cada uma dessas funcionalidades como um fluxo de negócio. Sendo assim, solicitar viagens, efetuar pagamentos via carteira virtual e recompensar usuários são fluxos de negócio do aplicativo e podem ser definidos como sagas.

Além disso, cada uma dessas sagas dependem de serviços diversos e esses serviços são considerados participantes da saga. Dá uma olhada na sequência de etapas necessárias para que a viagem ocorra:

Olhando só para a imagem anterior, não faz sentido dizer que a escolha do trajeto e o pagamento são serviços diferentes? Poderíamos utilizar, por exemplo, a API do Google Maps para manipular informações geoespaciais enquanto o pagamento envolve interações com APIs do mercado financeiro. Encontrar o motorista mais adequado para a viagem também não é uma tarefa trivial: além de ser um ponto geoespacial, o motorista faz parte da base de usuários do aplicativo. Logo, faz sentido dizer que o fluxo de negócio para solicitar uma viagem depende de três serviços/participantes: trajeto, motorista e pagamento.

Tá, mas onde as transações locais se encaixam nisso tudo? 🤔

Ainda que o fluxo dependa de três serviços, cada um deles é independente entre si, ou seja, cada serviço pode ter sua própria base de dados e é aqui que entram as transações locais. Como cada serviço possui uma base de dados, toda ação executada dentro desse mesmo serviço é uma transação local e pode beneficiar-se de propriedades ACID.

A imagem a seguir ilustra a saga para solicitar uma viagem e suas transações locais.

Beleza, fluxo de negócio é saga, serviço é um participante da saga e transação local é uma ação executada em um serviço, é isso? 😎

É isso, mas não só isso… Infelizmente, nem sempre a viagem vai acontecer como o esperado. Imagina se perto do passageiro não existe nenhum motorista, parece improvável né? Mas não é e precisamos nos preocupar com esses casos! Para que isso seja possível, para cada transação local que efetua alguma atualização na base de dados, existe uma transação de compensação utilizada para desfazer as mudanças.

Ok, agora é preciso entender como cada transação local de uma saga é acionada, para isso usamos um processo chamado coordenação de sagas.

Coordenação de Sagas

No mundo das sagas, as transações locais são acionadas via mensageria: assim que cada transação local é finalizada, uma mensagem é publicada para informar que aquela ação foi executada com sucesso e as próximas podem ser acionadas. Em caso de violação das regras de negócio de uma determinada transação local, uma mensagem também deve ser publicada a fim de desencadear as transações de compensação necessárias.

Um termo importante aqui é o acionamento: cada transação local age de acordo com o evento recebido, mas quem coordena esses acionamentos? De modo geral, podemos categorizar essa coordenação de sagas em dois tipos principais: coreografia e orquestração.

Coreografia

A coordenação de sagas via coreografia é como uma dança: cada participante conhece os seus passos e sabe reagir aos passos de seus parceiros sem a necessidade de alguém para guiá-los.

Nesse tipo de coordenação, cada participante da saga se inscreve nos canais de eventos de interesse e agem de acordo com os eventos publicados nesses canais.

A principal vantagem dessa abordagem é a simplicidade: não há a necessidade de definir um ponto central para coordenar as sagas e cada participante é responsável por conhecer os canais de interesse e reagir aos eventos recebidos.

Entretanto, como desvantagem, temos o risco de acoplar os participantes, dado que cada um deles precisa se inscrever em todos os canais de interesse e, conforme a quantidade de participantes aumenta, a quantidade de inscrições e complexidade também aumentará.

Orquestração

Já a coordenação de sagas via orquestração, como seu próprio nome indica, é muito mais parecida com uma orquestra na qual existe um maestro guiando os participantes.

Nesse tipo de coordenação, um orquestrador é responsável por enviar os eventos que acionam os participantes e também receber as respostas quando uma ação é finalizada. De acordo com as respostas, o orquestrador sabe qual ação deve ser executada, sendo essa ação acionar o próximo participante ou desencadear as transações de compensação. Dessa forma, cada participante é responsável apenas pelo seu próprio canal que recebe eventos e não precisa se inscrever nos canais de outros participantes.

A principal vantagem desse tipo de coordenação de sagas é a separação de responsabilidades entre os participantes da saga, dado que a lógica para acionar cada ação da saga fica exclusivamente no orquestrador.

Em relação às desvantagens, esse tipo de abordagem é mais complexa e adiciona mais um possível ponto de falha (o orquestrador). Normalmente, a orquestração é mais recomendada em casos de sagas com vários participantes e canais de comunicação.

Ufa! Acabou né? 🤯

Bom, não… Se você entendeu bem o conceito de transações ACID, deve ter percebido que o padrão Saga não garante o isolamento. Mas isso é assunto pra outro artigo, por hoje ficamos aqui, até mais! 😉

--

--