DDD: decidere quando orientarsi verso l'eventuale coerenza transazionale

3

Sto leggendo la serie di articoli di Vaughn Vernon su design aggregato efficace .

A proposito di decidere tra coerenza transazionale vs eventuale, si afferma quanto segue:

Discussing this with Eric Evans revealed a very simple and sound guideline. When examining the use case (or story), ask whether it's the job of the user executing the use case to make the data consistent. If it is, try to make it transactionally consistent, but only by adhering to the other rules of aggregate. If it is another user's job, or the job of the system, allow it to be eventually consistent. That bit of wisdom not only provides a convenient tie breaker, it helps us gain a deeper understanding of our domain. It exposes the real system invariants: the ones that must be kept transactionally consistent. That understanding is much more valuable than defaulting to a technical leaning.

Questo consiglio mi confonde. Ampie parti del software che ho scritto nella mia carriera sono state utili all'utente finale perché le ha liberate dalla responsabilità di mantenere i dati coerenti. Di conseguenza, gli utenti si aspettano di osservare costantemente uno stato coerente, senza ritardo . Per un cliente che paga un software che raggiunge la coerenza, ogni stato incoerente osservato è un bug.

Nella mia esperienza, quando si invia una richiesta, gli utenti di solito preferiscono aspettare un po 'e osservare uno stato coerente rispetto a una risposta immediata che viene modificata in seguito per essere coerenti.

Inversamente, quando è responsabilità dell'utente raggiungere la coerenza, il nostro sistema lo avviserà delle incongruenze, ma gli consentirà eventualmente di raggiungere la coerenza eseguendo diversi comandi più piccoli, invece di richiedere all'utente di fare quindi con un comando gigante.

Perché Evans e Vernon consigliano la coerenza definitiva quando è compito del sistema ottenere coerenza e coerenza transazionale quando è responsabilità dell'utente?

Potrebbe indicare vincoli di esempio e casi d'uso in cui la coerenza transazionale o finale è considerata adeguata in base alla regola precedente?

    
posta blubb 01.06.2018 - 19:28
fonte

2 risposte

3

Esiste un principio fondamentale sui microservizi che non può essere negato. I microservizi sono entità indipendenti; se stai costruendo un sistema basato su microservizi, quindi per definizione non puoi farli dipendere da un'autorità di dati centrale (come un database relazionale), perché i tuoi microservizi non sarebbero più essere indipendente. Fornendo a ciascun microservizio un proprio archivio dati indipendente, è necessario accontentarsi di un'eventuale coerenza.

Ovviamente non deve essere così. Potresti certamente collegare tutti i tuoi "microservizi" a un archivio dati centrale e ottenere la coerenza transazionale ovunque; il modello attore lo fa sempre. Solo che non so che i puristi chiamerebbero un'architettura di microservizi.

Penso che il punto di Vernon Vaugn sia che l'Utente non è generalmente responsabile per il raggiungimento della coerenza; il sistema è. La coerenza è un requisito non funzionale; non ha la forma "Come utente, voglio [eseguire qualche azione] in modo che io possa [raggiungere un obiettivo]."

Detto questo, gli utenti si aspettano che alcune interazioni (come lo spostamento di denaro da un conto corrente a un altro) siano coerenti dal punto di vista della transazione, non alla fine coerenti. Non vuoi che un cliente di una banca chieda "dove sono finiti i miei soldi", solo per farlo apparire nell'account di destinazione ore dopo.

    
risposta data 01.06.2018 - 20:00
fonte
2

This advice confuses me.

Non è colpa tua.

I sospetto che stia cercando di esprimere idee simili a quelle di Udi Dahan in Quando evitare CQRS ; una distinzione tra casi d'uso collaborativi e non collaborativi.

Considera un controllo registrati; un libro mastro di voci che descrivono ogni strumento negoziabile che si disegna su un account. Ogni voce includerebbe in genere l'identificatore univoco per il controllo (l'account a cui si riferisce è solitamente implicito - ogni registro è associato a un singolo account), un campo memo, l'importo e un saldo corrente.

Tale bilancia corrente deriva dai dettagli del controllo stesso e dalla precedente voce del bilancio nel registro (stato). Non ci sono in genere le voci di sorpresa da altre, o la congestione dal provare a registrare più assegni contemporaneamente. Quindi è ragionevole affermare invariante che il saldo corrente debba corrispondere al totale accumulato delle voci.

D'altro canto, ottenere il saldo del registro per abbinare il saldo del conto è più complicato - il saldo del conto dipenderà da altri collaboratori che depositano gli assegni, trasferiscono i fondi, accreditano l'account. Pertanto, il lavoro di provare a riconciliare il totale parziale nel registro con il totale dell'account può (e dovrebbe) essere rimandato a un momento successivo.

    
risposta data 02.06.2018 - 06:05
fonte