La modifica di record del database da parte di più utenti
-
08-06-2019 - |
Domanda
Ho progettato tabelle del database (normalizzato, su un MS SQL server) e creato un standalone di windows front-end di un'applicazione che sarà utilizzato da una manciata di utenti di aggiungere e modificare le informazioni.Aggiungere una interfaccia web per permettere la ricerca attraverso la nostra zona di produzione in una data successiva.
Mi preoccupa il fatto che se due utenti di iniziare a modificare lo stesso record quindi l'ultimo a commettere l'aggiornamento dovrebbe essere il 'vincitore' e informazioni importanti possono essere persi.Una serie di soluzioni che vengono in mente, ma non so se ho intenzione di creare un grande mal di testa.
- Non fare nulla e sperare che due utenti non sono mai intenzione di essere di modificare lo stesso record, allo stesso tempo. - Potrebbe non accadde, ma se non lo fa?
- La modifica di routine potrebbe archiviare una copia dei dati originali, così come gli aggiornamenti e quindi confrontare quando l'utente ha finito di modificare.Se differiscono mostrare all'utente e confermare l'aggiornamento - Avrebbe bisogno di due copie di dati da memorizzare.
- Aggiungere ultimo aggiornamento colonna DATETIME e controllare le partite quando si aggiorna, se poi non vedi differenze. - richiede una nuova colonna in ciascuna delle relative tabelle.
- Creare un modifica la tabella che registra quando l'utente avvia la modifica di un record che sarà controllato e impedire ad altri utenti di modifica dei record. - richiede attenta pensiero del flusso di programma, per evitare situazioni di stallo e record di diventare bloccato se un utente si blocca il programma.
Ci sono soluzioni migliori o devo andare per uno di questi?
Soluzione
Se si prevede che non frequenti collisioni, La Concorrenza Ottimistica è probabilmente la vostra scommessa migliore.
Scott Mitchell ha scritto una guida esaustiva su come implementare il modello:
L'Attuazione Di Concorrenza Ottimistica
Altri suggerimenti
Un approccio classico è il seguente:
- aggiungere un campo booleano , "bloccato" per ogni tabella.
- impostare a false per impostazione predefinita.
quando un utente avvia la modifica, fare questo:
- blocca la riga (o l'intera tabella se non è possibile bloccare la riga)
- controllare il flag sulla riga che si desidera modificare
- se il flag non è vero quindi
- informare l'utente non può modificare la riga al momento
- altro
- impostare il flag a true
rilasciare il blocco
quando si salva il record, impostare il flag su false
SELEZIONARE PER AGGIORNARE e mezzi equivalenti sono buone fornendo tenere premuto il blocco per una microscopica quantità di tempo, ma per un macroscopico quantità (es.l'utente dispone dei dati caricati e non ha premuto il tasto "salva" si dovrebbe utilizzare la concorrenza ottimistica come sopra.(Che penso sempre è misnamed, è più pessimista di 'ultimo scrittore di successo", che è di solito l'unica altra alternativa considerata.)
@ Mark Harrison :SQL Server non supporta la sintassiSELECT ... FOR UPDATE
).
SQL Server equivalente è il SELECT
dichiarazione suggerimento UPDLOCK
.
Vedere Documentazione Online di SQL Server per ulteriori informazioni.
-prima di creare presentata (tempo di aggiornamento) per memorizzare ultimo aggiornamento record -quando un qualsiasi utente di selezionare i record salva selezionare il tempo, confrontare per selezionare il tempo e il tempo di aggiornamento di campo se( tempo di aggiornamento) > (select tempo) che significa un altro utente di aggiornare questo record dopo selezionare record
Un'altra opzione è di verificare che i valori del record che si sta cambiando sono ancora gli stessi di quando hai iniziato:
SELECT
customer_nm,
customer_nm AS customer_nm_orig
FROM demo_customer
WHERE customer_id = @p_customer_id
(visualizza il customer_nm campo e l'utente cambia)
UPDATE demo_customer
SET customer_nm = @p_customer_name_new
WHERE customer_id = @p_customer_id
AND customer_name = @p_customer_nm_old
IF @@ROWCOUNT = 0
RAISERROR( 'Update failed: Data changed' );
Non è necessario aggiungere una nuova colonna alla tabella (e tenerlo aggiornato), ma è necessario creare più dettagliato di istruzioni SQL e pass nuovo e vecchio campi di stored procedure.
Essa ha anche il vantaggio che non è il blocco del record, perché si sa che il record di finire rimanendo bloccato quando essi non devono essere...
Il database di fare questo per voi.Guardare "select ...per l'aggiornamento", che è stata progettata proprio per questo genere di cose.Essa vi darà un blocco di scrittura per le righe selezionate, che si può quindi eseguire il commit o il rollback.
Con me, il modo migliore che ho una colonna lastupdate (timetamp tipo di dati).quando selezionare e aggiornare basta confrontare questo valore un altro anticipo di questa soluzione è che si può utilizzare questa colonna per rintracciare i dati in tempo è il cambiamento.Penso che non è buono se non si può semplicemente creare una colonna come isLock per il controllo dell'aggiornamento.