Concorrenza (Was: Overbooking)

Lorenzo propone un interessante e frequente problema di gestione "atomica" di verifica e prenotazione di un posto.
Ignorando per un momento le pur necessarie distinzioni fra prenotazione di posti numerati e non, una soluzione tecnologica esiste (in questo non concordo in pieno col commento di Alessandro), e rappresenta una sorta di pattern per questa situazione. Il pattern in particolare è ideale per le applicazioni di commercio elettronico in cui la conferma della vendita deve essere data on-line (quindi con conferma della disponibilità di magazzino).

La soluzione consiste appunto nel rendere atomica l'operazione di verifica e prenotazione, trasformando l'operazione di ricerca in un "update temporaneo". Alla domanda dell'operatore del cinema "Quanti posti le servono?" l'utente risponde con un numero, che l'operatore usa come input alla ricerca. A questo punto il sistema non "cerca" (SELECT) i posti, ma li "prenota" (UPDATE) direttamente, diciamo a nome di quell'operatore (e non dell'utente). Nel caso il cui la "ricerca/prenotazione" fallisse, cioè aggiornasse un numero di record inferiore a quello richiesto, si fa il rollback ed è necessario ripetere. Nel caso invece in cui l'utente procedesse al "checkout" i posti vengono a lui assegnati definitivamente.

La subottimalità introdotta da questo meccanismo è che si rendono temporaneamente indisponibili quei posti per cui l'operatrice ha fatto una verifica, positiva, ma che poi l'utente al telefono decide di non prendere. Vale più o meno lo stesso con il carrello di un utente anonimo in una applicazione di commercio elettronico.

Ovviamente questa è una delle strade possibili. Sono curioso di seguire il seguito della discussione.

Un'ultima nota: il termine overbooking è in realtà improprio in questo contesto, ma credo che il contenuto del post di Lorenzo chiarisca di cosa si sta parlando

powered by IMHO

Print | posted on giovedì 27 gennaio 2005 12.59

Feedback

# re: Concorrenza (Was: Overbooking)

left by Alessandro Petrozzelli at 27/01/2005 14.44 Gravatar
Con il tuo post, a mio avviso, non fai altro che confermare il mio punto di vista che, si badi bene, era ben lontano dall'affermare l'impossibilità tecnologica di una soluzione in proposito.
In sostanza: hai scelto una strada (lock pessimistico) piuttosto che l'altra (lock ottimistico).
Dipendentemente dal contesto può essere la scelta giusta piuttosto che no.
Tuttavia, proprio con lo scenario che proponi come esemplificativo, potrei obiettare: chi glielo dice al committente dell'ipotretico sito di web commerce che, sia pure per pochi istanti (ma potrebbero essere minuti...sai al telefono si fa presto a perdere il senso del tempo...) non sarà possibile acquistare niente da nessun'altro?
Non solo: hai presente cosa succede se provi a fare un update su un insieme di righe senza dare commit e da un'altra sessione provi a fare la stessa cosa su un insieme con almeno una riga in comune?
La fruibilità del servizio ne sarebbe seriamente (forse è un eufemismo) compromessa.
Ricorda che lock (logico o fisico) significa serializzazione.
Serializzazione implica "niente concorrenza".

# re: Concorrenza (Was: Overbooking)

left by Eugenio Schininà at 27/01/2005 14.55 Gravatar
Ciao Alessandro.
Chiaramente non c'era critica nei confronti del tuo lucido post. La soluzione da me descritta ha in effetti una componente "di comportamento". Intendevo semplicemente indicare che l'obiettivo da perseguire è, come dici tu, quello della serializzazione. Perdonami se ho interpretato male il tuo primo periodo.
Non capisco invece lo scenario da te illustrato nel commento. Probabilmente non sono stato abbastanza chiaro. Supponiamo che io, utente del sito di ecommerce, prima ancora di aver fatto il login, "compro" l'ultima copia del libro. Solo quella copia non sarà disponibile agli altri utenti, almeno fino a quando la mia sessione non scade. Il lock non sarebbe su tutti i prodotti. Inoltre non ho mai suggerito :-) di fare un update senza commit. Primo update con ID dell'operatore, poi o update per conferma cliente, oppure update per "liberare" le risorse preallocate.

# re: Concorrenza (Was: Overbooking)

left by Lorenzo Melato at 27/01/2005 14.57 Gravatar
Ciao Eugenio,

leggendo superficialmente il tuo post, dico che effettivamente potrebbe essere una soluzione praticabile. Era tra le possibili soluzioni che avevo pensato anch'io... anche se, come diceva il post di alessandro, effettivamente si sposta la soluzione al dominio del problema. La segretaria verifica la presenza di posti liberi (assegnadoli temporaneamente con l'update), se va tutto bene OK, se no si ricomincia.

Però, sono d'accordo con la critica di Alessandro, cioè, cosa succede se 2 segretarie tentano la verifica/assegnazione allo stesso istante ? mi pare sensato pensare che aprire una transazione (commit) sia effettivamente un po' troppo pesante.

# re: Concorrenza (Was: Overbooking)

left by Eugenio Schininà at 27/01/2005 15.06 Gravatar
Ciao Lorenzo.
Visto che l'argomento pare interessante, vale la pena di approfondire.
Come detto ho potuto sperimentare il pattern descritto nel caso di applicazioni di ecommerce: "enne" utenti anonimi (che vedono o meno la disponibilità dei prodotti) decidono di comprare lo stesso oggetto, che guarda caso è l'ultimo disponibile. E' chiaro che per quanto possano essere "contemporanei" i loro click, solo uno (il primo) sarà in grado di mettere il prodotto nel proprio carrello, mentre l'update degli altri lo vedrà già "comprato". L'operazione di update è serializzabile, senza bisogno di transazioni.
A questo punto può succedere che quell'utente faccia il login, e poi il checkout, e quel prodotto esce definitivamente dalle disponibilità. In alternativa può succedere che la sessione venga chiusa. In tal caso il prodotto viene reso nuovamente disponibile.
Non so se troverò il tempo necessario nei prossimi giorni, ma mi piacerebbe provare a modellare questo pattern anche per convincerMi della sua robustezza.
Grazie a tutti per il feedback.

# re: Concorrenza (Was: Overbooking)

left by Lorenzo Melato at 27/01/2005 15.19 Gravatar
Ciao Eugenio,

scusa la mia poca esperienza, ma cosa intendi quando dici: "L'operazione di update è serializzabile, senza bisogno di transazioni".

Intendi dire forse fare una roba tipo:

UPDATE tblPlaces SET fPostoOccupato=true WHERE IdPoltrona=4 AND fPostoOccupato=false

se il posto è libero l'update funziona e occupa il posto, se invece era già occupato non funziona e bisogna tentare con un'altra poltrona.

Questo però va bene se devi pre-prenotare una sola poltrona, ma se ne devi prenotare 5, ovviamente tutti gli UPDATE devono essere atomici, e come si fa a fare una cosa del genere senza usare una transazione?

# re: Concorrenza (Was: Overbooking)

left by Eugenio Schininà at 27/01/2005 15.51 Gravatar
Purtroppo qui la differenza fra "posti numerati e non" non è più irrilevante, e quindi non può essere più ignorata.
Si, intendo una cosa come quella, solo che non metto occupato, ma l'id dell'operatore o della sessione, in modo da poter sempre distinguere. Se i posti sono numerosi....

UPDATE tblPlaces SET PostoOccupatoDa="IdSessione" WHERE (IdPoltrona=4 or IDPoltrona=5 or IdPoltrona=6) AND PostoOccupatoDa IS NULL.

In questo caso il semplice lock al livello di record mi dovrebbe garantire (ma correggetemi se sbaglio) che il set di dati rimanga coerente nell'esecuzione del comando. Questo vuol dire che l'update della singola riga viene serializzato (messo in coda) con qualunque altra operazione analoga concorrente.

Se "RowsAffected" è < 3....

UPDATE tblPlaces SET PostoOccupatoDa=NULL WHERE PostoOccupatoDa="IdSessione"

Ripeto: la soluzione è subottimale in quanto occupa temporaneamente dei posti che in realtà rischiano di non essere confermati. Ciò è accettabile?

Nel caso del commercio elettronico la cosa è "leggermente" più facile in quanto gli item di un certo tipo sono tutti intercambiabili, cosa che non avviene evidentemente nel caso dei posti numerati al cinema.

# re: Concorrenza (Was: Overbooking)

left by Lorenzo Melato at 27/01/2005 17.14 Gravatar
Il fatto è che anche se effettivamente l'Update fatto così venisse messo in coda e fosse intrinsecamente atomico (ho qualche dubbio in proposito), nello specifico dominio del problema descritto bisognerebbe utilizzare per forza una transazione, altrimenti potrebbe succedere che, ad esempio, solo 2 delle tre poltrone non siano occupate. In tal caso l'update fatta così imposterebbe comunque 2 poltrone occupate invece di 3.

utilizzando una transazione o si occupano tutti e tre i posti o nessuno.

# Gestire il problema dell'overbooking

left by Pingback/TrackBack at 27/01/2005 18.10 Gravatar
Gestire il problema dell'overbooking
Comments have been closed on this topic.