Tag: microservices, distributed-transactions, event-driven, choreography, orchestration, eventual-consistency
Livello: avanzato
TL;DR: Pattern per la gestione di transazioni distribuite nei microservizi, basato su una sequenza di transazioni locali seguite da azioni di compensazione in caso di errore.
Evita il two-phase commit (2PC) che crea colli di bottiglia nei sistemi distribuiti.
Suddivide una transazione globale in una catena di transazioni locali (step).
Ogni step aggiorna il proprio database locale e pubblica un evento o messaggio.
Se uno step fallisce, la saga avvia le transazioni di compensazione per annullare gli step precedenti.
Coreografia: i microservizi reagiscono agli eventi in modo decentralizzato senza un controllore.
Orchestrazione: un componente centrale coordina il flusso, inviando comandi e gestendo lo stato.
Garantisce la consistenza eventuale, rinunciando alla consistenza forte immediata (ACID).
Le modifiche parziali sono visibili (dirty reads) poiché manca l'isolamento transazionale nativo.
Q: Quando scegli l'orchestrazione invece della coreografia?R: Uso l'orchestrazione quando la transazione coinvolge molti servizi, per evitare accoppiamento ciclico e mantenere la logica del workflow in un solo punto.
Q: Come gestisci il fallimento di un'operazione che non si può annullare?R: Isolo le azioni irrevocabili (come l'invio di una email al cliente) mettendole come ultimo step della saga.
Q: Cosa succede se l'operazione di compensazione fallisce a sua volta?R: Salvo gli eventi su una dead-letter queue, prevedo retry automatici e, se persistono, richiedo un intervento manuale o allarmi.
Q: Come mitighi l'assenza di isolamento nelle saghe?R: Uso lock semantici, ad esempio impostando lo stato dell'entità a "PENDING" in attesa che la saga completi il suo giro.
Dimenticare l'idempotenza: i sistemi di messaggistica possono consegnare gli eventi più volte, i consumer devono gestirlo.
Coreografie complesse: oltre i tre o quattro servizi diventa difficile tracciare il flusso di esecuzione e fare debugging.
Progettare saghe sincrone: il sistema deve restare asincrono, non si devono bloccare le risorse in attesa della fine della saga.