Identificazione dei record durante la progettazione di una regolazione web api

1

La nostra applicazione consente agli utenti di leggere / aggiungere / modificare / eliminare record di tabelle tramite l'interfaccia utente. Per impedire agli utenti concorrenti di modificare la stessa riga della tabella (scenari di record non aggiornati) utilizziamo un identificatore di riga e un campo di versione delle righe nella tabella. Queste operazioni sono ora esposte anche attraverso i servizi web. Per riutilizzare il codice, l'API di lettura è stata progettata per restituire l'ID di riga e i valori di versione di riga dal database in modo che gli stessi valori possano essere passati nella regola api per identificare una riga nella tabella. Quindi, se un utente vuole modificare le righe in una tabella, deve prima recuperarlo usando la read api per ottenere l'ID di riga e amp; versione di fila per ogni riga. Questi valori devono essere quindi passati alla regola api call in modo che il sistema identifichi la riga corretta ed esegua l'operazione di modifica.

Capisco che ci sono due problemi con un tale disegno api

  1. I dettagli del database interno sono esposti tramite le API
  2. Prestazioni: al momento la chiamata a api di regolazione deve essere abbinata alla chiamata api di lettura.

Per quanto riguarda il business, abbiamo un concetto di campi chiave nella tabella che definisce l'unicità funzionale. Potremmo utilizzare questi campi definiti dall'utente per identificare la riga, ma come eviteremmo aggiornamenti di riga simultanei senza la versione di riga?

Hai qualche suggerimento su come potrebbe essere progettata l'API per soddisfare i requisiti aziendali? Qualsiasi esempio del mondo reale che possa essere referenziato.

Grazie.

    
posta Andy Dufresne 13.10.2017 - 07:15
fonte

2 risposte

1

Questo è un argomento che interessa fondamentalmente ogni applicazione multiutente. È possibile avere utenti diversi che modificano lo stesso elemento di dati contemporaneamente. Ci sono 2 soluzioni:

Blocco ottimistico : è praticamente ciò che hai implementato, utilizzando un numero di versione su ciascun elemento di dati. Quando si salva l'elemento dati dopo la modifica, si controlla che il numero di versione nel database sia ancora quello caricato. Se non lo è, vuol dire che qualcuno ha aggiornato l'oggetto nel frattempo, quindi mostrerai un messaggio di errore all'utente, che dovrà ricaricare l'elemento dati e riapplicare le modifiche.

Questa soluzione funziona bene nei casi in cui la probabilità di modifiche simultanee è piccola e quando le modifiche a un elemento sono relativamente piccole, ovvero l'utente non perderebbe un paio d'ore di lavoro se qualcuno modificasse il proprio elemento di dati modificato.

Modificato: per essere più specifico per il tuo caso reale: non vedo un problema con l'esposizione dei numeri di versione, in quanto non sono informazioni riservate. Li restituiresti come parte della riga modificata, quindi non ci sarebbe alcun impatto sulle prestazioni.

A seconda di quanto è pubblica la tua API e di quanto ti fidi dei tuoi clienti, puoi risolvere il problema rivelando gli ID e le versioni creando alias temporanei e archiviandoli in una tabella o in una cache. Quindi il cliente otterrebbe l'ID abcd, che internamente ti mappa all'ID Database 1 e ID versione 3. Tuttavia dovresti farlo ogni volta che restituisci un elenco di record al client, da cui scegliere quale desidera per modificare, quindi sarebbe un grande sovraccarico.

Blocco pessimistico : implementeresti un servizio di blocco e lo chiameresti per ottenere un blocco sul tuo elemento di dati prima di poterlo modificare. Dopo aver salvato avresti rilasciato il blocco. Ciò significa che solo un utente può modificare l'elemento in una volta.

Tuttavia presenta alcuni inconvenienti. Per uno è necessario implementare il servizio di blocco, quindi è necessario implementare un meccanismo di timeout, nel caso in cui qualcuno inizi a modificare qualcosa e poi a casa o in vacanza. Potrebbe anche essere necessario un modo per un amministratore di rilasciare i blocchi manualmente sugli elementi dati, se ci sono blocchi in attesa di un timeout, ma gli utenti devono lavorarci urgentemente.

    
risposta data 13.10.2017 - 11:16
fonte
0

Aggiungi un'operazione di blocco.

  • Il client invia un LockId generato casualmente
  • Sever controlla se il record è bloccato. se non lo blocca e memorizza il LockId contro quella riga
  • Se già bloccato, restituisci "Bloccato per la modifica"

Quindi l'operazione di modifica.

  • Il client invia le modifiche e ha usato LockId
  • in precedenza
  • Il server controlla che LockId sul record corrisponda a quello inviato. In tal caso, modifica e sblocca

Questa è la versione di base del pattern. Puoi migliorarlo con timeout, modificare richieste, ecc.

    
risposta data 13.10.2017 - 11:10
fonte

Leggi altre domande sui tag