Modello di transazioni di compensazione

Azure

Quando si utilizza un'operazione coerente finale costituita da una serie di passaggi, il modello di transazione di compensazione può essere utile. In particolare, se uno o più passaggi hanno esito negativo, è possibile usare il modello di transazione di compensazione per annullare il lavoro eseguito dai passaggi. In genere, si trovano operazioni che seguono il modello di coerenza finale nelle applicazioni ospitate nel cloud che implementano processi e flussi di lavoro aziendali complessi.

Contesto e problema

Le applicazioni eseguite nel cloud modificano spesso i dati. Questi dati vengono talvolta distribuiti tra diverse origini dati in posizioni geografiche diverse. Per evitare conflitti e migliorare le prestazioni in un ambiente distribuito, un'applicazione non deve provare a offrire coerenza transazionale assoluta. Deve invece implementare la coerenza finale. Nel modello di coerenza finale, un'operazione aziendale tipica è costituita da una serie di passaggi separati. Mentre l'operazione esegue questi passaggi, la visualizzazione generale dello stato del sistema potrebbe essere incoerente. Tuttavia, al termine dell'operazione e tutti i passaggi sono stati eseguiti, il sistema dovrebbe diventare di nuovo coerente.

L'introduzione alla coerenza dei dati fornisce informazioni sul motivo per cui le transazioni distribuite non vengono ridimensionate correttamente. Questa risorsa elenca anche i principi del modello di coerenza finale.

Una sfida nel modello di coerenza finale è come gestire un passaggio che ha esito negativo. Dopo un errore, potrebbe essere necessario annullare tutto il lavoro eseguito nei passaggi precedenti nell'operazione completata. Tuttavia, non è sempre possibile eseguire il rollback dei dati, perché altre istanze simultanee dell'applicazione potrebbero averlo modificato. Anche nei casi in cui le istanze simultanee non hanno modificato i dati, l'annullamento di un passaggio potrebbe essere più complesso del ripristino dello stato originale. Potrebbe essere necessario applicare varie regole specifiche dell'azienda. Per un esempio, vedere il sito Web di viaggio descritto nella sezione Esempio più avanti in questo articolo.

Se un'operazione che implementa la coerenza finale si estende su più archivi dati eterogenei, l'annullamento dei passaggi nell'operazione richiede di visitare a sua volta ogni archivio dati. Per evitare che il sistema rimanga incoerente, è necessario annullare in modo affidabile il lavoro eseguito in ogni archivio dati.

I dati interessati da un'operazione che implementa la coerenza finale non sono sempre contenuti in un database. Si consideri ad esempio un ambiente SOA (Service-Oriented Architecture). Un'operazione SOA può richiamare un'azione in un servizio e causare una modifica nello stato mantenuto da tale servizio. Per annullare l'operazione, è anche necessario annullare questa modifica dello stato. Questo processo può comportare la chiamata del servizio di nuovo e l'esecuzione di un'altra azione che inverte gli effetti del primo.

Soluzione

La soluzione consiste nell'implementare una transazione di compensazione. I passaggi di una transazione di compensazione annullano gli effetti dei passaggi nell'operazione originale. Un approccio intuitivo consiste nel sostituire lo stato corrente con lo stato in cui si trovava il sistema all'inizio dell'operazione. Tuttavia, una transazione di compensazione non può sempre adottare questo approccio, perché potrebbe sovrascrivere le modifiche apportate ad altre istanze simultanee di un'applicazione. Al contrario, una transazione di compensazione deve essere un processo intelligente che tiene conto di qualsiasi lavoro svolto da istanze simultanee. Questo processo è in genere specifico dell'applicazione, in base alla natura del lavoro eseguito dall'operazione originale.

Un approccio comune prevede l'uso di un flusso di lavoro per implementare un'operazione coerente che richiede la compensazione. Man mano che l'operazione originale procede, il sistema registra informazioni su ogni passaggio, incluso come annullare il lavoro eseguito dal passaggio. Se l'operazione ha esito negativo in qualsiasi momento, il flusso di lavoro torna indietro nei passaggi completati. In ogni passaggio, il flusso di lavoro esegue il lavoro che inverte tale passaggio.

Due punti importanti sono:

  • Una transazione di compensazione potrebbe non dover annullare il lavoro nell'ordine inverso esatto dell'operazione originale.
  • Potrebbe essere possibile eseguire alcuni passaggi di annullamento in parallelo.

Questo approccio è simile alla strategia sagas descritta nel blog di Clemens Vasters.

Una transazione di compensazione è un'operazione coerente alla fine, quindi può anche avere esito negativo. Il sistema deve essere in grado di riprendere la transazione di compensazione al momento dell'errore e continuare. Potrebbe essere necessario ripetere un passaggio che ha esito negativo, pertanto è necessario definire i passaggi in una transazione di compensazione come comandi idempotenti. Per altre informazioni, vedere Idempotency Patterns (Modelli di Idempotenza ) nel blog di Jonathan Oliver.

In alcuni casi, l'intervento manuale potrebbe essere l'unico modo per eseguire il ripristino da un passaggio non riuscito. In queste situazioni, il sistema deve generare un avviso e fornire il maggior numero possibile di informazioni sul motivo dell'errore.

Considerazioni e problemi

Quando si decide come implementare questo modello, tenere presente quanto segue:

  • Potrebbe non essere facile determinare quando un passaggio di un'operazione che implementa la coerenza finale ha esito negativo. Un passaggio potrebbe non riuscire immediatamente. Al contrario, potrebbe essere bloccato. Potrebbe essere necessario implementare un meccanismo di timeout.

  • Non è facile generalizzare la logica di compensazione. Una transazione di compensazione è specifica dell'applicazione. Si basa sul fatto che l'applicazione possieda informazioni sufficienti per poter annullare gli effetti di ogni passaggio di un'operazione non riuscita.

  • È necessario definire i passaggi in una transazione di compensazione come comandi idempotenti. In tal caso, i passaggi possono essere ripetuti se la transazione di compensazione stessa ha esito negativo.

  • L'infrastruttura che gestisce i passaggi deve soddisfare i criteri seguenti:

    • È resiliente nell'operazione originale e nella transazione di compensazione.
    • Non perde le informazioni necessarie per compensare un passaggio non riuscito.
    • Monitora in modo affidabile lo stato di avanzamento della logica di compensazione.
  • Una transazione di compensazione non restituisce necessariamente i dati di sistema allo stato all'inizio dell'operazione originale. Al contrario, la transazione compensa il lavoro che l'operazione è stata completata correttamente prima che non sia riuscita.

  • L'ordine dei passaggi nella transazione di compensazione non è necessariamente l'esatto opposto dei passaggi dell'operazione originale. Ad esempio, un archivio dati potrebbe essere più sensibile alle incoerenze rispetto a un altro. I passaggi della transazione di compensazione che annullano prima le modifiche apportate a questo archivio.

  • Alcune misure possono contribuire ad aumentare la probabilità che l'attività complessiva abbia esito positivo. In particolare, è possibile inserire un blocco basato sul timeout a breve termine su ogni risorsa necessaria per completare un'operazione. È anche possibile ottenere queste risorse in anticipo. Eseguire quindi il lavoro solo dopo aver acquisito tutte le risorse. Finalizzare tutte le azioni prima della scadenza dei blocchi.

  • La logica di ripetizione dei tentativi che è più forgiving del solito può aiutare a ridurre al minimo gli errori che attivano una transazione di compensazione. Se un passaggio di un'operazione che implementa la coerenza finale ha esito negativo, provare a gestire l'errore come eccezione temporanea e ripetere il passaggio. Arrestare l'operazione e avviare una transazione di compensazione solo se un passaggio ha esito negativo ripetutamente o non può essere recuperato.

  • Quando si implementa una transazione di compensazione, si riscontrano molte delle stesse sfide che si riscontrano quando si implementa la coerenza finale. Per altre informazioni, vedere la sezione "Considerazioni per l'implementazione della coerenza finale" in Nozioni di base sulla coerenza dei dati.

Quando usare questo modello

Usare questo modello solo per le operazioni che devono essere annullate in caso di errore. Se possibile, progettare soluzioni per evitare la complessità della richiesta di transazioni di compensazione.

Esempio

I clienti usano un sito Web di viaggi per prenotare gli itinerari. Un singolo itinerario può essere costituito da una serie di voli e alberghi. Un cliente che viaggia da Seattle a Londra e quindi a Parigi può seguire questa procedura durante la creazione di un itinerario:

  1. Prenotare un posto sul volo F1 da Seattle a Londra.
  2. Prenotare un posto sul volo F2 da Londra a Parigi.
  3. Prenotare un posto sul volo F3 da Parigi a Seattle.
  4. Prenotare una camera nell'hotel H1 a Londra.
  5. Prenotare una camera nell'hotel H2 a Parigi.

Questi passaggi costituiscono un'operazione coerente, anche se ogni passaggio è un'operazione separata. Oltre a eseguire questi passaggi, il sistema deve anche registrare le operazioni del contatore per annullare ogni passaggio. Queste informazioni sono necessarie nel caso in cui il cliente annulla l'itinerario. I passaggi necessari per eseguire le operazioni del contatore possono quindi essere eseguiti come transazione di compensazione.

I passaggi della transazione di compensazione potrebbero non essere l'esatto opposto dei passaggi originali. Inoltre, la logica in ogni passaggio della transazione di compensazione deve tenere conto delle regole specifiche dell'azienda. Ad esempio, l'annullamento di una prenotazione di volo potrebbe non autorizzare il cliente a un rimborso completo.

La figura seguente illustra i passaggi di una transazione a esecuzione prolungata per la prenotazione di un itinerario di viaggio. È anche possibile visualizzare i passaggi delle transazioni di compensazione che annullano la transazione.

Diagramma che mostra i passaggi per la creazione di un itinerario. Vengono visualizzati anche i passaggi della transazione di compensazione che annulla l'itinerario.

Nota

È possibile eseguire i passaggi della transazione di compensazione in parallelo, a seconda del modo in cui si progetta la logica di compensazione per ogni passaggio.

In molte soluzioni aziendali, l'errore di un singolo passaggio non richiede sempre il rollback del sistema usando una transazione di compensazione. Si consideri ad esempio lo scenario del sito Web di viaggio. Si supponga che i clienti libri i voli F1, F2 e F3, ma non possono prenotare una camera all'hotel H1. È preferibile offrire al cliente una camera in un hotel diverso nella stessa città anziché annullare i voli. Il cliente può comunque decidere di annullare. In tal caso, la transazione di compensazione viene eseguita e annulla le prenotazioni per i voli F1, F2 e F3. Ma il cliente deve prendere questa decisione, non il sistema.

Passaggi successivi

  • Informazioni di base sulla coerenza dei dati. Il modello di transazioni di compensazione viene spesso usato per annullare le operazioni che implementano il modello di coerenza finale. Questo primer fornisce informazioni sui vantaggi e sui compromessi della coerenza finale.
  • Modelli di Idempotenza. In una transazione di compensazione, è consigliabile usare idempotenti comandi. Questo post di blog descrive i fattori da considerare quando si implementa idempotenza.
  • Modello di supervisore dell'agente di pianificazione. Questo articolo descrive come implementare sistemi resilienti che eseguono operazioni aziendali che usano servizi e risorse distribuite. In questi sistemi, a volte è necessario usare una transazione di compensazione per annullare il lavoro eseguito da un'operazione.
  • Modello di ripetizione dei tentativi. Le transazioni di compensazione possono essere richieste in modo computazionale. È possibile provare a ridurre al minimo l'uso usando il modello Di ripetizione dei tentativi per implementare un criterio efficace di ripetizione delle operazioni non riuscite.
  • Modello di transazioni distribuite saga. Questo articolo illustra come usare il modello Saga per gestire la coerenza dei dati tra microservizi in scenari di transazione distribuiti. Il modello Saga gestisce il ripristino degli errori con transazioni di compensazione.
  • Pattern Pipe e Filtri. Questo articolo descrive il modello Pipe e Filtri, che è possibile usare per decomporre un'attività di elaborazione complessa in una serie di elementi riutilizzabili. È possibile usare il modello Pipe e Filtri con il modello di transazione di compensazione come alternativa all'implementazione di transazioni distribuite.
  • Progettazione per la correzione automatica . Questa guida illustra come progettare applicazioni di auto-guarigione. È possibile usare transazioni di compensazione come parte di un approccio di auto-guarigione.