Idempotenza e concorrenza in un servizio Web REST

3

La concorrenza e l'idempotenza si escludono a vicenda per un servizio web REST o può essere fatto in modo che un servizio possa essere sia concorrente che idempotente? L'utilizzo di una metodologia di blocco ottimistico come l'utilizzo della proprietà Version sembra impedire a un metodo di essere idempotente se non sbaglio?

Ad esempio, supponiamo che tu abbia l'utente A che desidera aggiornare Person.Name

Current Person.Version = 1

Set utente A

Person.Name = "Name X"
Person.Version = 2

Ora Person.Version = 2

Utente A invia la stessa richiesta, con valore Person.Version = 2 . Fallisce perché ti aspetti il Person.Version valore 3 .

    
posta dstr 29.06.2016 - 12:34
fonte

2 risposte

4

Is concurrency and idempotency mutually exclusive for a REST web service or can it be done so a service can be both concurrent and idempotent?

Sì, naturalmente

User A send same request, with Person.Version = 2 value. It fails because you expect the Person.Version value 3.

Penso che tu stia confondendo un paio di idee diverse.

Da Gregor Hohpe

The term idempotent is used in mathematics to describe a function that produces the same result if it is applied to itself, i.e. f(x) = f(f(x)).

In Messaging this concepts translates into the a message that has the same effect whether it is received once or multiple times. This means that a message can safely be resent without causing any problems even if the receiver receives duplicates of the same message.

Quindi la prima cosa da notare nel tuo sistema è che l'effetto sul ricevitore di inviare lo stesso messaggio due volte è lo stesso di inviarlo esattamente una volta.

Il vantaggio è che è sicuro che il mittente ripeta il messaggio tutte le volte che è necessario per ricevere ack .

Ora, nel tuo esempio, sembra che ti aspetti qualcosa oltre a ciò, ovvero che il messaggio ripetuto genera la stessa risposta. Questa è una proprietà fantastica per il tuo sistema, ma richiede un po 'più di lavoro.

La trama di base è che il tuo server riceve il messaggio duplicato e controlla se è già stato gestito. Un approccio ingenuo sarebbe quello di esaminare la versione e verificare se la modifica applicata in questa versione è già stata applicata.

In particolare, il server riceve il secondo messaggio, vede che è già nella versione 2, vede che il nome è attualmente uguale a "Person X" e restituisce successo!

Non è una grande risposta se qualcun altro scivola in un'altra modifica tra i messaggi duplicati.

Una vera implementazione è più complicata - la forma base è di tenere traccia delle risposte che invii e quando ricevi un messaggio duplicato, rispondi alla risposta stessa che hai inviato prima . Udi Dahan copre questo approccio. La persistenza delle risposte è nel modello di dominio, quindi la messaggistica è ancora stateless, che soddisfa il vincolo REST.

    
risposta data 29.06.2016 - 15:28
fonte
0

In un ambiente concorrente, l'accesso ai dati segue sempre il teorema di Cap . Vale a dire, hai una scelta di implementazione tra le seguenti:

  • Blocco globale di lettura / scrittura, ovvero senza disponibilità elevata
  • cache locali, ovvero nessuna coerenza tra i client
  • Sistema centralizzato, ovvero limiti di scala

In un servizio REST classico, gli aggiornamenti vengono inviati direttamente al DB che saprà decidere cosa fare con i tuoi dati, molto probabilmente, manterrà solo l'aggiornamento più recente. Se hai bisogno di un sistema versionned dovresti aggiungere nuove righe invece di aggiornare quelle vecchie.

    
risposta data 29.06.2016 - 13:29
fonte

Leggi altre domande sui tag