9

Sono un po 'confuso riguardo al flusso in un sistema che utilizza eventi di dominio per creare il modello letto. In particolare, come affrontiamo il fatto che l'utente si aspetta che i dati (e la sua vista) cambino quando completano un comando, ma a causa della nostra architettura di sistema (chiamate non bloccanti per pubblicare eventi) il database effettivo potrebbe non cambiare prima del la pagina è ricaricata?Visualizzazione delle modifiche in Visualizza quando si utilizza CQRS e DDD con Domain Events & ServiceBus

Spero di spostare la progettazione di uno dei nostri sistemi più in linea con CQRS utilizzando eventi e un bus di servizio.

Diciamo che il mio flusso va come ad esempio: il tasto scatta

  1. utente in Vista per eseguire compito di rimuovere Metodo di pagamento dal loro account.

  2. Il controller chiama PaymentMethodRemovalService, passando il suo accountId & paymentMethodId.

  3. Controller utilizza AccountRepository per recuperare account e chiama account.RemovePaymentMethod (id)

  4. account convalida può accadere che il funzionamento e pubblica evento PaymentMethodRemovedMessage (accountid, paymentMethodId)

  5. Perché la pubblicazione eventi è asincrona, ora dobbiamo tornare dal servizio e restituire la vista dal controller - ma i nostri dati attuali non sono ancora aggiornati!

  6. Un gestore, IHandle < PaymentMethodRemovedMessage>, sente l'evento e rimuove la riga reale dal DB

Allora, che cosa è un ragazzo di fare?

Potrei semplicemente, ad esempio, rimuovere il div che stava visualizzando il metodo di pagamento. Questo potrebbe funzionare in uno scenario AJAX, ma cosa succede se sto usando Post-Redirect-Get per supportare client non JavaScript. Quindi sparerò il mio Get e leggerò i dati dal lato Query delle cose, potenzialmente prima che vengano aggiornate.

Viene visualizzata una notifica in cui è stata inviata la richiesta di rimozione del metodo di pagamento? (Che non sembra amichevole, ha senso per l'invio di un ordine, ma non per, diciamo, cambiando un indirizzo).

Esiste un modo per riconciliare le modifiche di implementazione come eventi asincroni disaccoppiati e mostrare i dati utente che riflettono la loro modifica corrente?

EDIT: La mia domanda è molto simile a CQRS, DDD synching reporting database devo dire, la risposta data lì e anche accennato qui, ha un po 'di un odore ad esso - litigare l'interfaccia utente per mostrare un aggiornamento che è fuori della band con il DB letto, per così dire. Speravo in qualcosa di un po 'più pulito.

risposta

8

Se si è bloccati nel modello di richiesta/risposta, è possibile adottare un modello di richiesta/risposta correlato. Per informazioni specifiche, controlla l'esempio di pagine asincrone nel download NSB. Ciò dimostra la richiesta/risposta in un'impostazione ASP.NET. Ci sono alcuni esempi di ASP.NET MVC là fuori se questo è più il tuo problema.

Quando si introduce l'elaborazione asincrona si accetta che i dati saranno obsoleti.Si può obiettare che nel momento in cui si interroga il DB i dati sono già vecchi (latenza di rete, tempo di rendering ecc.). Poiché i dati sono già vecchi, dobbiamo chiederci quanti anni ha?

Un'altra cosa da considerare è che il trattamento è un po 'fuori uso. Il passaggio 3 dovrebbe convalidare il comando prima di inviarlo al server e quindi i passaggi 3, 4 verrebbero dopo 6. Il database dovrebbe essere aggiornato solo se il comando è valido e l'evento deve essere pubblicato solo se il database viene aggiornato correttamente.

0

Questo problema viene definito come 'Coerenza Eventuale'. Ci sono modi chiari per affrontarlo. Il primo punto da fare è che ogni sistema ha una coerenza finale se sta usando o meno eventi asincroni. È solo che hai deciso di renderlo esplicito mentre la maggior parte degli altri sistemi fa aspettare all'utente che l'aggiornamento sia completato. Entrambi gli approcci sono validi purché siano scelti esplicitamente.

Qualche tempo fa ho scritto un post su questo argomento, che si possono trovare utili. Potete trovare qui: 4 Ways to Handle Eventual Consistency on the UI

Ecco una versione breve:

Opzione 1 - Utilizzare una schermata di conferma. Se utilizzi un'applicazione bancaria sul tuo telefono, probabilmente l'hai vista in azione. Trasferisci un po 'di denaro e alla fine del processo, tieni indirizzato a una schermata di conferma prima di essere riportato ai tuoi account. Questo dà al sistema il tempo di tornare aggiornato.

Opzione 2 - fingere. Se l'operazione che l'utente sta tentando ha molte probabilità di successo, quindi fingere di farlo può essere un approccio legittimo. Questo è spesso usato quando si acquistano i biglietti che sono molto richiesti. La tua transazione potrebbe passare, ma in seguito la società scoprirà che il tuo biglietto è già stato venduto millisecondi prima. Il vantaggio per l'azienda è che hanno la vendita piuttosto che rischiare di perdere entrambi i clienti. Fintanto che il sistema è stato progettato con cura, questa situazione dovrebbe raramente verificarsi e quindi non essere un problema nel complesso.

È inoltre possibile utilizzare correlazione id per consentire di sottoscrivere successo o il fallimento delle operazioni.

In ogni caso, la speranza che fornisce alcuni spunti di riflessione.