DDD: Perché è una cattiva pratica aggiornare più root aggregati per transazione?

3

Citando Vaughn Vernon:

When two or more Aggregates have at least some dependencies on updates, use eventual consistency.

Inoltre continua a suggerire che si potrebbero fare uso di Eventi di dominio per pubblicare azioni sugli altri root aggregati che devono essere aggiornati.

Procede inoltre a spiegare che Eventuale coerenza potrebbe essere un male necessario.

Che cosa rende l'aggiornamento di più Aggregate Roots in una richiesta / transazione come una cattiva pratica?

    
posta Nik Kyriakides 22.08.2017 - 19:30
fonte

2 risposte

1

Da tutto ciò che ho letto, qui e altrove, la ragione sembra essere che la modifica di più aggregati in una transazione crea il requisito che siano memorizzati sullo stesso host di database . (Non consideriamo nemmeno il commit a due fasi.)

Questo introduce un trade-off, che rende questa considerazione piuttosto che una regola del pollice .

Il tuo contesto limitato in questione verrà mai diviso tra più host di database? Non più database - questo non è un problema. Database host .

A meno che non si elaborino volumi incredibili o si stiano facendo male a scegliere gli indici delle tabelle, la maggior parte dei contesti utilizzerà sempre un solo host di database. Ciò consente di disporre di transazioni di database su più modifiche aggregate (all'interno di un contesto limitato). Ciò rende le garanzie di coerenza molto più semplici.

Tutto considerato, preferisco il processo decisionale come questo:

  1. È sufficiente che gli aggregati siano alla fine coerenti? In tal caso, utilizza la coerenza finale.
  2. Possiamo ragionevolmente aspettarci che gli aggregati vivano sempre su un singolo host di database? In tal caso, consenti loro di condividere la stessa transazione del database. (Si noti che se gli aggregati si trovano in contesti limitati diversi , la risposta qui è probabilmente "no".)
  3. Abbiamo bisogno di più host e coerenza garantita. Solo ora dobbiamo saltare attraverso i cerchi, perché i nostri requisiti sono pesanti. Risolvi il problema grazie alla progettazione.

Per fare un esempio di # 3:

  • Il contesto di bilancia tiene traccia del saldo di ciascun titolare.
  • Il saldo di un titolare non deve essere negativo.
  • Il contesto di pagamento vuole spendere parte del saldo di un inquilino. La detrazione deve essere immediatamente coerente (per garantire la regola precedente). Se il pagamento fallisce, il saldo deve alla fine risalire.
  • Il contesto Balance espone nella sua API un metodo che restituisce una nuova prenotazione, riducendo il saldo di un importo richiesto o restituendo un errore se tale importo non è disponibile.
  • Il contesto Saldo consuma eventi dal contesto Pagamento.
  • Alcuni eventi aumentano il saldo di un titolare.
  • Gli altri eventi riguardano una diminuzione del saldo del locatario e sono sempre collegati a una prenotazione precedente. Confermano la prenotazione.
  • Le prenotazioni sono valide per un breve periodo, ad es. 5 minuti. Le prenotazioni non confermate entro quel tempo sono invertite, aumentando il saldo da compensare.

Si noti che questo esempio richiede la garanzia che ogni evento sia gestito esattamente una volta . In particolare, nessun evento deve mai essere saltato! È fattibile, ma è difficile riuscire a farlo. La maggior parte degli strumenti non è a tenuta stagna in questo senso. Il punto di errore più facilmente identificato è se il server delle applicazioni si arresta in modo anomalo dopo aver aggiornato il suo database, ma prima di pubblicarne gli eventi. Garantire una consegna degli eventi esattamente una volta è una discussione utile a sé stante.

    
risposta data 29.08.2018 - 16:49
fonte
11

What makes updating multiple Aggregate Roots in one request/transaction such a bad practice?

Il problema è il contrario: provare a modificare più aggregati in una singola transazione è un'indicazione che non hai modellato correttamente i tuoi limiti aggregati.

In altre parole: la modifica di due diversi aggregati nella stessa transazione introduce un vincolo sul loro storage (gli aggregati devono essere memorizzati nello stesso database) e tale vincolo non si riflette nel modello . È effettivamente implicito.

    
risposta data 23.08.2017 - 04:45
fonte

Leggi altre domande sui tag