Masalah Anda bermuara pada pertanyaan "apa yang seharusnya menjadi kunci sinkronisasi" . Dari pertanyaan Anda tampaknya pemesanan tersebut bukan pemesanan barang tertentu. Tapi mari kita asumsikan, bahwa pengguna memesan kamar hotel tertentu sehingga Anda perlu menyelesaikan dua masalah:
- mencegah pemesanan berlebih (mis. memesan barang yang sama untuk dua orang)
- mencegah kesalahan perhitungan status akun paralel
Jadi, ketika pengguna mencapai titik ketika dia akan menekan konfirmasi tombol, ini adalah skenario yang mungkin dapat Anda terapkan:
-
mulai transaksi
-
mengunci entri pengguna sehingga proses paralel diblokir
SELECT * FROM user FOR UPDATE WHERE id = :id
-
cek ulang saldo rekening dan lempar exception/rollback jika dana tidak mencukupi
-
mengunci item yang akan dipesan untuk mencegah overbooking
SELECT * FROM room FOR UPDATE WHERE id = :id
-
cek kembali ketersediaan booking dan lempar exception/rollback jika barang sudah dipesan
-
buat entri pemesanan dan kurangi dana dari akun pengguna
-
komit transaksi (semua kunci akan dilepaskan)
Jika, dalam kasus Anda, Anda tidak perlu memeriksa pemesanan berlebih, lewati / abaikan langkah 4 dan 5.