Come risolvere la coerenza di invio dei moduli in un'applicazione web?

6

Immagina di avere un modulo con cui puoi modificare alcuni dati, chiamiamolo modulo Persona. Immaginiamo che un utente apra questo modulo Persona, riceva i dati correnti che sono memorizzati nel database e inizi a modificarlo. Durante questo periodo, un altro utente apre lo stesso modulo Persona, riceve gli stessi dati Person, esegue rapidamente alcune modifiche e restituisce i dati modificati in questo modo continuando a conservarli.

Ora il primo utente che ha aperto il modulo Persona vuole anche mantenere le sue modifiche. Invia il modulo, ma c'è un problema: i dati che questo utente ha modificato non sono più coerenti con il database / non sono aggiornati (a causa delle modifiche del secondo utente). Cosa faresti adesso? Come risolveresti questo problema di coerenza?

    
posta user3357969 20.08.2018 - 19:39
fonte

3 risposte

10

Questo è un problema piuttosto comune e uno dei motivi per cui le applicazioni Web tendono a impegnarsi subito dopo ogni modifica. A volte la risposta giusta non fa nulla. Devi decidere in anticipo come intendi farlo in ordine di complessità:

  • L'ultimo commit vince (comportamento predefinito)
  • Blocca attivamente il record per impedire modifiche
  • Aggiorna schermata se vengono rilevate modifiche
  • Risolvi i conflitti dopo il tentativo di commit (ultimo perché è meno favorevole)

Il comportamento che stai vivendo ora è che l'ultima persona che salva le modifiche vince. Non è sempre una risposta sbagliata, in particolare se la quantità di dati è piuttosto piccola.

Il blocco attivo può essere un dolore necessario se si stanno impegnando molte modifiche contemporaneamente. L'overhead per essere in grado di supportare un'appropriata fusione dei record è piuttosto alto, quindi è più facile impedire ad altre persone di essere in grado di modificare il record. Avrai bisogno di espirare naturalmente i lucchetti se l'utente dimentica di sbloccare il record.

Le app a singola pagina (o app desktop) hanno il lusso di poter fornire un livello di integrazione molto più granulare. È utile se si consente il server push a chiunque abbia quel record aperto. Quando hai la possibilità di inviare notifiche di modifica, l'interfaccia utente può aggiornare l'interfaccia utente per riflettere ciò che è attualmente sul server. Nel caso in cui qualcun altro stia modificando il codice, puoi almeno vedere cosa c'è sul server accanto a ciò che hai digitato. Questo è piuttosto complicato, ma se è possibile inviare patch dalla SPA al back-end e viceversa, è possibile. Ancora meglio, se l'interfaccia utente ha un solo controllo in modalità di modifica alla volta, le modifiche sono molto più dettagliate.

L'ultima opzione è usare il controllo di versione sui dati e rilevare la versione dei dati che stai modificando è vecchia sul server. In tal caso, è possibile inviare una risposta per consentire all'utente di modificare manualmente i conflitti. Questa è un'esperienza utente piuttosto schifosa dal momento che è sull'utente cercare e trovare dove sono cambiate le cose.

Bottom Line

Devi scegliere quale dei molti modi per gestire questo problema si adatta meglio alla tua applicazione. A volte l'utente richiede blocchi di record attivi. A volte richiederanno la versione altamente interattiva. Ci sono dei compromessi, quindi dovrai lavorare con la tua comunità di utenti per selezionare realmente ciò che funzionerà meglio dal punto di vista dell'impegno / tempo.

    
risposta data 20.08.2018 - 20:12
fonte
1

Per la maggior parte dei casi, sto suggerendo una strategia di risoluzione delle collisioni basata sulla versione. La versione può essere implementata come un ulteriore incremento di campo dopo il commit. Se qualcuno ha modificato la versione precedente (non la più recente):

  1. Genera un'eccezione - non consentita.
  2. Scrivi un campo per gli oggetti di campo che uniscono il codice.
  3. Sostituisci con gli ultimi dati del modulo.

1 e 3 pro e contro sono chiari. 2 ha bisogno di alcuni conflitti per risolvere la logica.

Unione. La linea di base che ha modificato i campi senza conflitti applicati sia da changeset che da conflitti sta risolvendo campo per campo. I conflitti di campo risolvono i conti con gli stessi principi di 1-3, in modo ricorsivo, se si hanno oggetti nidificati.

    
risposta data 22.08.2018 - 04:58
fonte
0

In breve:

  • Aggiungi una colonna alla tabella che contiene un "numero di versione" per il record.
  • Recupera questa colonna insieme agli altri campi che mostri all'utente.
  • Nell'applicazione, prima di inviare una modifica, eseguire un calcolo sul valore del "numero di versione" (solo aggiungendo uno funziona abbastanza bene).
  • Includere il "numero di versione" in qualsiasi istruzione di aggiornamento. NON eseguire questo calcolo in linea nell'SQL (che, essendo eseguito lato server, mina l'intero punto dell'esercizio).
  • Nel Database, implementa un Trigger che reagisce agli aggiornamenti. In questo Trigger, eseguire lo stesso calcolo sul valore "numero di versione" attualmente nel record del database (il "vecchio" valore passato nel Trigger). Se il risultato di questo calcolo non corrisponde a quello inviato dall'applicazione, rifiuta l'aggiornamento (genera un'eccezione).
  • Nell'applicazione, prendere questa eccezione e invertire l'aggiornamento al valore "numero di versione" o altrimenti impedire all'utente di inviare nuovamente i dati [ora obsoleti].
risposta data 21.08.2018 - 13:14
fonte

Leggi altre domande sui tag