Ditt problem kokar ner till frågan om "vad ska synkroniseringslåset vara" . Av din fråga verkar det som att bokningen inte är bokning av en specifik vara. Men låt oss anta att en användare bokar ett specifikt hotellrum så du måste lösa två problem:
- förhindra överbokning (t.ex. boka samma sak för två personer)
- förhindra felberäkning av parallellkontotillstånd
Så när en användare kommer till en punkt när han/hon är på väg att trycka på bekräfta knappen, är detta ett möjligt scenario som du kan implementera:
-
påbörja transaktionen
-
lås användarposten så att parallella processer blockeras
SELECT * FROM user FOR UPDATE WHERE id = :id
-
kontrollera kontosaldot igen och kasta undantag/återställning om det inte finns tillräckligt med pengar
-
lås varan som ska bokas för att förhindra överbokning
SELECT * FROM room FOR UPDATE WHERE id = :id
-
kontrollera bokningstillgängligheten igen och kasta undantag/återställning om varan redan är bokad
-
skapa bokningspost och dra av pengar från användarens konto
-
commit transaktion (alla lås kommer att släppas)
Om du i ditt fall inte behöver kontrollera om det finns överbokning, hoppa över / ignorera steg 4 och 5.