Busca avançada

Transações em Microservices e CQRS

quinta-feira, 17 de janeiro de 2019 por Eduardo Spaki
Transações em Microservices e CQRS

Muito se houve falar hoje em dia sobre conceitos como microservices, ou “separação” das operações de escrita das operações de leitura com o CQRS (ou até mesmo CQS). Ao mesmo tempo em que vem à tona questões antigas: como fazer uma transação ou garantir operações atômicas!?

Pois é, não dá! Simples assim!?

O problema é que são propostas diferentes… bem diferentes daqueles softwares desktop dos anos 90 que se conectam e um database na terceira forma normal! 

Microservices e CQRS tem entrado em voga recentemente, pela necessidade de atender grandes operações que podem ser distribuídas em diversos servidores, contrapondo o antigo senso de centralizar tudo em um único lugar.

Isso quer dizer que os sistemas desenvolvidos antigamente estavam errados? Não! De maneira alguma. Há contextos em que ela funciona, e há outros em que temos que sair da caixa para explorar oportunidades.

Um DBMS (Database Management System - Sistema de Gerenciamento de Banco de Dados), como por exemplo um Oracle, propõe uma gestão centralizada, normalizada e relacional de dados, com operações ACID (Atômica/Indivisível, Consistente, Isolada e Durável), transações e afins, através de uma base SQL, por exemplo. 

Já conceitos como CQRS (Command Query Responsibility Segregation) ou CQS (Command Query Separation) defendem que há uma separação de responsabilidade entre comandos que escrevem informações, e os que lêem (em muitos casos fisicamente). O que seria mais fácil: fazer um Full Text Search em um Oracle ou em um Elasticsearch!? Como garantir Atomicidade em uma operação que escreve em duas fontes de dados de tecnologias distintas?

Um sistema tradicional de database, como um SQL Server, tem essa política centralizadora, até mesmo para garantir o ACID, partindo do princípio que, quando a questão é desempenho, o hardware do mesmo deve ser escalado (mais memória, mais discos, discos mais rápidos, rede, etc), ou seja, uma escala vertical. 

Se houver uma escala horizontal (adicionando máquinas paralelas em cluster), começa a “dor de cabeça” de gerenciar estado entre a mesma informação transitando em diferentes nós do cluster. O que poderia resultar em um lock, até que a informação já estivesse toda atualizada dentro da grid, gerando gargalo.

Por isso que quando alguém me faz um questionamento mais ou menos assim: Quero usar CQRS, mas não vi nenhum exemplo usando transação. Sabe como faz? - Me vem um episódio do Chaves na cebeça:

•    Chaves: O que deseja para comer?
•    Dona Neves: Um flan, com biscoitos.
•    Chaves: Não vamos ter biscoitos.
•    Dona Neves: Então me veja um sorvete de baunilha… com biscoitos?
•    Chaves: Não temos biscoitos.
•    Dona Neves: Me veja só um café, então. Com biscoitos.
•    Chaves: Não tem biscoito!
•    Dona Neves: Mas não tem nada nesse restaurante!?

As vezes ouvimos o hype, aquela modinha da vez, e vem aquele sentimento do impostor de não saber aquilo… parece vergonhoso não usar, afinal: já pensou o vexame se o seu projeto não estiver no Docker em um Kubernates!?

Pois então, sendo sincero, eu não passo vergonha alguma ao entregar um projeto para o cliente, do jeitinho que ele pediu! 

E se ele pediu um sistema que poderia ser atendido simples e puramente com um ASP.NET MVC, não vou ficar gastando horas de projeto, consequentemente o dinheiro dele, por capricho de garantir que 10 instâncias do site irão rodar para atender todos os 5 usuários do sistema!

Obviamente que quando me pedem para garantir que um e-commerce aguente uma demanda de blackfriday, pensamos em técnicas e ferramentas para isso… e aqui faz sentido o cenário de microservices, CQRS, etc. Bem como não faz sentido algumas transações… ou vai me dizer que na sua última compra de Blackfriday, você recebeu sua Nota Fiscal imediatamente após o clique do botão “Finalizar”!? Teve amigo meu que recebeu mais de uma semana depois, porque demorou esse tempo para processar o pedido… Já imaginou um lock desses no database!?

E isso é uma teoria comprovada! Ou seja, não estou inventando nada. Se chama: Teorema CAP (Consistency, Availability, Partition Tolerance - Consistência, Disponibilidade, Tolerância a Particionamento), do DR Eric Brewer, hoje líder de infraestrutura no Google.

Falando em Google, leia também o texto que eu escrevi explicando como a organização, mesmo sem querer, pode ter ajudado a hackear a sua empresa ou seus dados.

Apenas lembrando que teoria é uma proposição ainda não comprovada. Teorema é uma teoria experimentada e comprovada.

Acho que a principal lição aqui é que não preciso ser purista de escolher uma ou outra, mas devemos assumir que há cenários, ou melhor ainda, funcionalidades, onde podemos optar por colocar CQRS. Já em outras operações, podemos optar por ter uma transação ACID.

Imagine um caso onde há uma solução com microservices, um catálogo de produtos com CQRS e uma consolidação de transações financeiras com database relacional + transactions + ACID. Não seria um cenário válido!?

Vou terminar de forma provocativa: apesar de não existir transações em microservices, há um conceito conhecido como Saga… mas isso é conteúdo para outro post.

A questão aqui é que, você irá se atentar para programar e desenvolver as regras de negócio do seu software ou usar o dinheiro do cliente para construir ferramental de atomicidade em computação distribuída?
 

Compartilhar

Eduardo Spaki
Autor
Eduardo Spaki

Arquiteto de Soluções da Code 21. Atua há 14 anos com desenvolvimento de tecnologias, tendo participado de projetos em diversos países. É especialista em softwares para a Internet e possui MBA em Gerência de Projetos. Já publicou livro e artigos na área de tecnologia e vem palestrando sobre carreira profissional, inovação e TI. Se deseja viabilizar seu software web ou mobile, migrar para nuvem ou implantar ferramentas de TI, entre em contato com ele pela Code 21.