2 sesi akan terlihat seperti ini:
user = Student.query.with_for_update(of=Student, nowait=True).filter(Student.id == 122).first()
user.type = 1
db.session.commit()
dan
user = Student.query.with_for_update(of=Student, nowait=True).filter(Student.id == 122).first()
user.type -= 1
db.session.commit()
Agar FOR UPDATE
untuk bekerja dengan baik, semua transaksi yang terlibat yang bermaksud untuk memperbarui baris perlu menggunakannya.
Dalam contoh Anda, sesi 2 tidak menggunakan with_for_update
. Karena Anda tidak menyuruhnya menggunakan FOR UPDATE
, bebas untuk membaca nilai lama dari baris (karena nilai baru belum dikomit, dan kunci tidak memblokir pembaca murni), kemudian memodifikasi nilai dalam memori tersebut, lalu menulisnya kembali.
Jika Anda tidak ingin menggunakan FOR UPDATE
di mana pun Anda membaca baris dengan maksud untuk mengubahnya, Anda dapat menggunakan isolation level serializable
di mana pun. Namun jika Anda melakukannya, hal-hal mungkin tidak memblokir, melainkan akan tampak berhasil sampai komit, kemudian membuang kesalahan serialisasi yang perlu ditangkap dan ditangani.
Catatan: Contoh pra-edit Anda seharusnya berfungsi karena kedua sesi diberi label dengan with_for_update
.