qual è la procedura migliore per sincronizzare le richieste cercando di aggiornare la stessa risorsa nelle API RESTful?

5

Questa domanda non riguarda un quadro specifico. ma al momento sto lavorando con asp.net core.

Il problema che sto affrontando è l'aggiornamento simultaneo di una risorsa nell'applicazione web (race condition). Non sto parlando di sincronizzare le modifiche con un documento wiki, diciamo condizionali richieste HTTP. entrambe le richieste vengono ricevute contemporaneamente dall'applicazione Web. per esempio la prima richiesta richiede un database per ottenere un numero e poi prova ad incrementare quel numero di uno. nel frattempo, la seconda richiesta ottiene lo stesso numero prima che la prima richiesta confermi la sua modifica al DB. ora il numero è solo aumentato di uno. Ciò che mi viene in mente è il blocco di ogni risorsa quando viene aggiornata.

ci sono altre opzioni disponibili? questo deve essere un problema comune in ogni applicazione web ma non riesco a trovare molte soluzioni per questo problema su Internet.

    
posta alizx 20.07.2017 - 15:23
fonte

1 risposta

6

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.

    
risposta data 20.07.2017 - 15:52
fonte

Leggi altre domande sui tag