CQRS: modello di scrittura query

2

Contesto: l'utente desidera modificare i dettagli dell'entità, ad esempio il nome utente.

Supponendo che il modello di lettura sia alla fine coerente con il modello di scrittura è concettualmente sbagliato interrogare il modello di scrittura per ottenere lo stato più recente di un'entità per la pagina?

Se scelgo di interrogare il modello di lettura (tipica implementazione in base al CQRS Journey Book) come posso gestire una concorrenza ottimistica?

Grazie in anticipo!

    
posta Stanislav O Chernykh 14.07.2015 - 13:53
fonte

4 risposte

3

Direi che l'interfaccia di comando non suppone query di supporto e il modello di scrittura non deve necessariamente essere esposto alle applicazioni client per questo scopo.

Tuttavia, la nozione che stai cercando nella prima domanda:

is it conceptually wrong to query write model in order to get the most recent state of an entity for the page?

sembra "leggere le tue stesse scritture", che può essere molto importante per alcune applicazioni. Suppongo che si possa fornire un buffer che ricordi le proprie scritture di sessione. Tuttavia, quello che faccio è un po 'diverso.

Rendo un timestamp (o qualche altro valore che supporta > = confronto) dall'interfaccia di comando, oltre all'interfaccia di query. I timestamp vengono inoltrati dal modello di scrittura al modello di lettura insieme ad altri contenuti (modificati).

Poi, quando è necessario leggere le mie scritture, le mie domande dei clienti che chiedono i dati di interesse a partire da > = il timestamp restituito dall'ultimo comando che ha emesso. In questo modo, so che la query sta segnalando il contenuto dell'ultima modifica del client.

Non capisco la domanda successiva:

If I choose to query the Read Model (typical implementation according to CQRS Journey Book) how can I deal with optimistic concurrency?

Come dice @Alexus, il modello letto è di sola lettura, quindi non deve preoccuparsi di più autori. Tuttavia non è totalmente di sola lettura in quanto deve essere ripetutamente aggiornato in qualche modo dal modello di scrittura. La concorrenza ottimistica dovrebbe essere gestita internamente dall'archivio SQL del modello di scrittura normalizzato e anche dall'archivio SQL del modello di lettura denormalizzato. (Se si sta utilizzando un archivio non SQL per il modello di lettura denormalizzato, è necessario tenere presente che esiste una differenza tra la risposta alle query del modello di lettura con valori obsoleti sulla strada verso l'eventuale coerenza e la risposta con valori misti incoerentemente sulla strada alla coerenza finale.)

Aggiornamento:

Scusa per la confusione da parte mia. Il termine concorrenza ottimistica è sovraccarico ... Questo termine normalmente (nella mia mente) si riferisce a un tipo di capacità di sovrapposizione delle transazioni trovata negli interni del database. Tuttavia, CQRS utilizza questo termine per riferirsi a una funzionalità simile tra l'applicazione client e il server di comando (e il server di query). Fornisci il timestamp (come descritto sopra) anche con i comandi, in una forma che chiede al comando di fallire / abortire se il timestamp è vecchio. Si noti che è consigliabile che ogni aggregato abbia il proprio timestamp per granularità fine, quindi stiamo parlando dell'uso della logica che ho descritto sopra per ciascun aggregato.

Quindi questo crea un ciclo completo o un ciclo per quanto riguarda i timestamp / i numeri di versione. Quando l'applicazione client esegue la prima query, omette il timestamp, sebbene riceva indietro il timestamp; quando esegue un comando che è (molto probabilmente) basato sulle informazioni della query al momento, passa nel timestamp della query con un flag per abortire sul timestamp precedente. Al termine del comando, viene fornito un timestamp che può essere utilizzato dalla query successiva per vedere se i risultati dell'ultimo comando sono ancora nel modello di lettura (o attendere fino a tale momento). La query restituisce nuovi timestamp e il comando successivo è basato su tali ultimi timestamp (con abort if old set) e così via. (A volte, se l'interfaccia utente sa che non è stata aggiornata in un istante, potrebbe farlo in modo preventivo.)

Penso che potresti iniziare con un unico timestamp globale / numero di versione per l'intero sistema; fatelo funzionare e in seguito rendete la data / ora più granulare (ad esempio per istanza aggregata) per una maggiore concorrenza. Come @JDT sta rispondendo, questo è già qualcosa di complicato, e molto di più se si prende tutto il modo di repliche dei processori di comando per lo stesso aggregato.

    
risposta data 14.07.2015 - 20:04
fonte
2

Concettualmente sbagliato? Direi: "Sì!"

Sembra che tu sia disposto a fare CRUD. Niente di intrinsecamente sbagliato in questo. Ma concettualmente non è il CQRS.

Se hai solo bisogno di CRUD per risolvere il tuo problema, usa CRUD.

    
risposta data 17.07.2015 - 17:30
fonte
0

Il modello di lettura non sarà influenzato dalla concorrenza ottimistica perché è di sola lettura e verrà restituito all'utente in qualsiasi stato si trovi al momento della richiesta. L'unica cosa di cui ti devi preoccupare è apportare modifiche allo stesso modello di scrittura contemporaneamente.

    
risposta data 14.07.2015 - 19:04
fonte
0

No, il modello letto è per la lettura, il modello di scrittura per la scrittura

Se si dispone di un sistema che richiede l'utilizzo di CQRS (ed è qualcosa su cui si dovrebbe riflettere a lungo e in modo approfondito), non è possibile utilizzare il modello di scrittura per ottenere i dati più recenti nell'interfaccia utente. Si progetta la propria applicazione in modo tale da poter gestire il ritardo tra l'operazione di scrittura e il modello di lettura eventualmente coerente. Se il ritardo è breve (ad esempio, due secondi o meno), è possibile lavorare con una pagina che visualizza semplicemente un messaggio all'utente in merito alle modifiche che sono state salvate, impedendo in tal modo all'utente di visualizzare dati incoerenti. Ritardi più lunghi potrebbero significare "falsificare" i dati persistendo nella sessione e mostrandoli da lì, nascondendo i campi che sono stati modificati e non sono ancora coerenti, e così via.

Fare un CQRS "puro" con un modello di lettura e scrittura ha molte, molto grandi implicazioni sul modo in cui scrivi la tua applicazione. Dovrebbe davvero considerare se l'applicazione è abbastanza grande da giustificare questo approccio in quanto molte cose che date per scontate in applicazioni regolari diventano meno ovvie o addirittura difficili.

    
risposta data 14.07.2015 - 22:45
fonte

Leggi altre domande sui tag