Quando usar transactions, melhores praticas
Comecei a trabalhar com nodejs tem mais de um ano e me pego diariamente em conflito com minha mente sobre o uso de transactions com arquitetura limpa. O que acontece é que os ORM do nodejs não fornecem um modo claro de como se trabalhar com transações entre varios arquivos. Os termos "Transação global", "Transação com escopo da requisição", são o que eu venho buscado, porem estou começando a acreditar que talves o modo que eu aprendi a usar transactions (laraboy) que seja errado. Então a minha duvida é, como vocês utilizam ? Como aprenderam a usar e quais boas praticas recomendam ?
consegue dar um exemplo mais completo do caso de uso que está querendo resolver?
Existem várias aplicações práticas, mas uma que eu gosto muito é quando você está trabalhamdo com threads e podemos pensar em uma entidade para os trabalhos jobs
que é populada por tarefas longas a serem executadas no background.
Num cenário hipotético, se você tiver 64 threads rodando em paralelo precisa de alguma forma garantir que não haverá uma race condition - por exemplo: dois ou mais processos pegarem um job e iniciarem a mesma tarefa.
Nesse caso você pode iniciar uma transaction, e fazer um "SELECT FOR UPDATE" na entidade jobs
que irá receber um lock até que essa transaction seja resolvida com um COMMIT ou um ROLLBACK. Isso garante que a thread/worker que pegou aquela tarefa faça o UPDATE na entidade atribuindo um PID
e finalmente te dá uma forma de um outro processo como watchdog monitorar se o PID ainda está em execução e todo processo dos threads correr de forma organizada.
Mas além dessa aplicação existem várias outras aonde, por exemplo, você tenha regra de negócio entre a Primary Key a Foreign Key e deseje fazer um rollback para não deixar uma entidade orders
sem itens
(um case bastante comum).
E de maneira bastante ampla existem várias aplicações, mas a regra é simples: se precisou de uma entidade atômica, então requer de uma transaction. Mas se ainda não ficou claro, posso dar outro último exemplo: imagine que seu sistema utilize Redis + Mongo + Postgres ou MySQL (comum em microsserviços), e uma entidade para ser salva no MySQL depende do Redis e do Mongo, você utiliza uma transaction para validar tudo e após inserir corretamente, você COMMITA a transação, se não faz rollback.
Espero ter ficado claro.
As transações principalmente em ORM mais maduras, seguem o mesmo protocolo e implementações parecidas. Agora voce falando de DDD, voce pode utilizar tanto no Laravel ou Express as transactions na sua camada de repository infra/repository/meu-banco
.
Caso voce precisar criar uma transação que afete mais de uma tabela por exemplo: CreateUserRepository
e CreateUserGroupRepository
é acho melhor seguir o conceito de responsabilidade única e também a regra do seu projeto. Se o seu usuário precisa de um grupo para existir, voce pode dentro do CreateUserRepository
já criar a transação dentro dele.
Caso voce queira abstrair a transação para outra camada, na aplication ou main
eu acho over, por que a transação só deveria existir na camanda de repository