Ho un sito Web in cui gli utenti possono acquistare i biglietti, ma le quantità dei biglietti sono generalmente limitate e vanno rapidamente. Sto cercando di implementare un sistema di deposito a garanzia in modo che un utente possa fare clic su quel numero di ticket x, a quel punto li inserirò in uno stato di deposito a garanzia. Questo dà loro diversi minuti per inserire i dati della carta di credito e completare l'acquisto.Operazioni atomiche MySQL e blocco tabella
Ho tre tabelle pertinenti: eventi, ticket e impegno. Una riga nella tabella degli eventi descrive l'evento stesso, incluso il numero massimo di biglietti disponibili.
La tabella biglietti detiene il seguente:
user_id: l'utente che ha acquistato i biglietti
number_of_tickets: quanti biglietti hanno acquistato
event_id: l'evento rilevante
Il piano di deposito di garanzia contiene quanto segue:
user_id: l'utente nel processo di acquisto dei biglietti
number_of_tickets: quanti biglietti che vogliono
event_id: l'evento rilevante
Attualmente, lo faccio tre MySQL domande, una per i ticket massimi, una per il numero di biglietti venduti e una per il numero di biglietti già in deposito. Poi ho calcolato:
$remaining_tickets = $max_tickets - $tickets_sold - $tickets_in_escrow;
if ($remaining_tickets >= $tickets_desired)
{
beginEscrow($user_id, $event_id, $tickets_desired);
}
else
{
echo "Error: not enough ticket remain.";
}
mio problema è che è possibile per più di un utente per essere eseguito il codice, allo stesso tempo. Se un utente dovesse chiamare beginEscrow
dopo il, un altro utente aveva già letto il numero di biglietti già in deposito, è possibile che io sovrastimerò lo spettacolo.
Sto utilizzando il motore InnoDB per i miei tavoli e ho letto come bloccare una singola riga utilizzando SELECT .... FOR UPDATE
, ma non sto aggiornando una singola riga. La funzione beginEscrow
inserirà semplicemente una nuova riga nella tabella di deposito. Calcolo $tickets_in_escrow
leggendo tutte le righe con l'ID evento corretto e sommando il numero di ticket in ognuno di essi.
Forse sto sbagliando tutto?
Devo bloccare l'intero tavolo?
Non posso essere il primo a scrivere un sistema di deposito di biglietti. Mi sono suicidato cercando di trovare qualche tutorial su questo genere di cose, ma ho suonato. Qualsiasi idea sarebbe utile.
Grazie!
Quindi, in altre parole, tutto il conteggio ticket di deposito deve essere in una singola riga in una singola tabella, piuttosto che una somma delle righe nella tabella di deposito. Capisco come abbia senso. Grazie. – user1493634
In realtà, tutto il conteggio dei ticket, disponibile, depositato e venduto, dovrebbe trovarsi in una singola colonna di una singola riga in una singola tabella. Quella colonna colpisce zero, non ci sono più posti da vendere. Ma tu hai l'idea. –
In StackOverflow, se una risposta ti aiuta devi accettarlo facendo clic sul segno di spunta verde. –