Devo bloccare le righe nel mio DB cloud mentre sono state modificate da un utente

12

Sto creando un'applicazione desktop che persiste i dati nel cloud. Una delle preoccupazioni che ho è un inizio per modificare un elemento nell'applicazione e lasciarlo per un po 'causando la stasi dei dati. Questo può ovviamente accadere anche se 2 persone provano a modificare lo stesso oggetto nello stesso momento. Quando finiscono la loro modifica e vogliono salvare i dati, avrei bisogno di sovrascrivere ciò che esiste attualmente nel database o controllare che abbiano iniziato a modificare dopo l'ultima modifica e forzarli a scartare le modifiche o dare loro la possibilità di rischiare sovrascrivere le modifiche di qualcun altro.

Ho pensato di aggiungere campi is_locked e lock_timestamp alla tabella DB. Quando un utente inizia a modificare l'elemento, la riga cambierà is_locked in true e imposterà il timestamp del blocco sull'ora corrente. Avrei quindi un po 'di tempo per il quale è tenuto il blocco (ad esempio 5 minuti). Se qualcun altro tenta di modificare l'oggetto, riceverà un messaggio che dice che l'oggetto è bloccato e quando il blocco scade automaticamente. Se l'utente si allontana mentre modifica il blocco scadrà automaticamente dopo un periodo di tempo relativamente breve e una volta che l'utente verrà avvisato che il blocco è scaduto e sarà costretto a riavviare la modifica dopo che i dati sono stati aggiornati.

Questo sarebbe un buon metodo per prevenire la sovrascrittura di dati non aggiornati? È eccessivo (non mi aspetto che l'applicazione venga utilizzata da più di alcune persone contemporaneamente su un singolo account).

(Un'altra preoccupazione che ho sono 2 persone che ottengono un lucchetto per lo stesso oggetto, tuttavia credo che sia una condizione di gara con cui mi trovo a mio agio.)

    
posta yitzih 08.01.2018 - 19:40
fonte

2 risposte

19

Una cosa che ti aiuterà qui è la terminologia. Quello che stai descrivendo qui è chiamato "blocco pessimistico". L'alternativa principale a questo approccio è "blocco ottimistico". Nel blocco pessimistico, ogni attore deve bloccare il record prima di aggiornarlo e rilasciare il blocco quando l'aggiornamento è completo. Nel blocco ottimistico, si presume che nessun altro stia aggiornando il record e provi. L'aggiornamento non riesce se il record è stato modificato da un altro attore.

Il blocco ottimistico è generalmente preferibile se la possibilità che due attori aggiornino la stessa cosa allo stesso tempo sia bassa. Il pessimista viene in genere utilizzato quando tale probabilità è elevata o è necessario sapere che il tuo aggiornamento sarà in grado di avere successo prima della partenza. Nella mia esperienza, il blocco ottimistico è quasi sempre preferibile perché ci sono molti problemi inerenti al blocco pessimistico. Uno dei maggiori problemi è toccato nella tua domanda. Gli utenti possono bloccare un record per la modifica e quindi partire per il pranzo. La tua mitigazione ti aiuterà in questo, ma l'esperienza dell'utente non sarà migliore dell'approccio ottimistico e rischia di essere molto peggio. Ad esempio, un utente apre un record, inizia ad aggiornarlo e il suo capo si presenta alla sua scrivania. Un altro utente tenta di modificare il record. È chiuso. Il secondo utente continua a provare e dopo 5 minuti, il blocco scade e il secondo utente aggiorna il record. Il primo utente torna sullo schermo, prova a salvare e gli viene detto che hanno perso il lucchetto. Ora nello stesso scenario con tutto lo stesso eccetto usando il blocco ottimistico, l'esperienza del primo utente è praticamente la stessa, ma il secondo utente non aspetta 5 minuti.

Lo schema che disponi sarebbe notevolmente migliorato implementando un blocco ottimistico per il valore di blocco, ma la mia impressione è che il blocco ottimistico è probabilmente OK per tutto il processo e puoi sbarazzarti del campo is_locked.

Non fornisci il "DB cloud" che stai utilizzando. Probabilmente dovresti esaminare le funzionalità di questo per vedere se ci sono funzionalità integrate per questo prima di implementare la tua soluzione.

Ecco la ricetta di base: invece di un campo is_locked, hai un campo numero di versione. Quando recuperi il record, estrai la versione corrente del record. Quando si aggiorna, si rende contingente l'aggiornamento sul campo della versione corrispondente a ciò che è stato recuperato e lo si incrementa in caso di successo. Se la versione non corrisponde, l'aggiornamento non ha alcun effetto e lo segnala come un errore.

    
risposta data 08.01.2018 - 20:18
fonte
0

Da alla risposta di @ JimmyJames , possiamo vedere come la domanda riguarda davvero esperienza utente .

Tutto dipende dal contesto. Quanto tempo e impegno ci vuole per aggiornare un record? Con quale frequenza più utenti desiderano aggiornare lo stesso documento?

Ad esempio, se i tuoi utenti di solito impiegano alcuni secondi per aggiornare il record e c'è poco contesa, il blocco ottimistico è probabilmente la strada da percorrere. Nel peggiore dei casi, un utente dovrà spendere qualche secondo in più, forse fino a un minuto, per aggiornare un documento.

Se il tuo documento è molto controverso ma ben strutturato, forse puoi consentire loro di bloccare singoli campi con incrementi di 30 secondi, mostrando un timer o una notifica non invadente per consentire loro di estendere il blocco.

Tuttavia, se i tuoi utenti dedicano una notevole quantità di tempo o impegno, dovresti prendere in considerazione altri approcci. Il tuo record è ben strutturato? Potresti mostrare agli utenti un confronto (una diff) tra la versione sul server e la versione che stanno cercando di salvare? Puoi evidenziare le differenze? Puoi lasciarli unire le modifiche? Pensa all'esperienza che vuoi avere con i tuoi strumenti di controllo del codice sorgente. Davvero non vuoi essere costretto a scrivere di nuovo tutto quel codice!

Puoi consultare Google Documenti per ulteriore ispirazione. Forse puoi mostrare agli utenti una notifica che è stata salvata una nuova versione. Forse puoi mostrare loro quante persone hanno il record aperto in modo che possano scegliere di tornare in un momento meno controverso.

    
risposta data 16.01.2018 - 08:06
fonte

Leggi altre domande sui tag