Questi problemi dovrebbero generalmente essere gestiti al livello più basso possibile, cioè nel database.
Le tue modifiche al database dovrebbero essere atomiche, quindi il processo di modifica del database non è interrompibile e riesce completamente o fallisce completamente. Nei database SQL, è possibile utilizzare le istruzioni START TRANSACTION
per farlo. Per esempio. è possibile utilizzare una transazione per rendere una tabella di sola lettura per altre connessioni per la durata della transazione. Poiché le transazioni coinvolgono blocchi, limitano le prestazioni. Ma nella maggior parte degli scenari, è più importante avere dati coerenti che avere dati corrotti più rapidamente.
Se non puoi utilizzare le transazioni (ad es. perché ci sono richieste HTTP tra la richiesta del numero e la modifica del numero), puoi fare un aggiornamento test-and-set: custodisci l'istruzione UPDATE
aggiungendo una clausola WHERE
che asserisce che la riga è nello stato previsto. Ad esempio, è possibile verificare manualmente che contenga ancora il valore precedente o aggiungere un timestamp o una colonna di versione per dati più complessi. È quindi necessario assicurarsi di aggiornare / incrementare quella colonna in ogni modifica alla riga. Se questa colonna è stata modificata, l'aggiornamento ha esito negativo.
In relazione a questo è l'idea di non aggiornare mai le righe ma aggiungere solo nuovi record. Quando si esegue una query sulla tabella, viene selezionato solo il risultato più recente. La tabella ora è più simile a un log delle transazioni. Tuttavia, questo è piuttosto vicino all'implementazione del proprio motore di database e ci sono database (possibilmente database NoSQL) che implementano direttamente questo comportamento.
In alcuni scenari, non è importante che ogni modifica sia applicato e applicato in ordine, ma solo che il risultato finale sia corretto. È quindi possibile semplicemente lasciare vincere l'ultimo aggiornamento. Ma ciò richiede che ogni aggiornamento fornisca i dati completi per il record e non aggiorni solo uno o due campi. Questa è spesso la soluzione più desiderabile in scenari distribuiti in cui è necessario sincronizzare più database, ad es. dati su un server e dati memorizzati nella cache su un dispositivo che può eseguire modifiche offline.