De 2 sessies zouden er als volgt uit moeten zien:
user = Student.query.with_for_update(of=Student, nowait=True).filter(Student.id == 122).first()
user.type = 1
db.session.commit()
en
user = Student.query.with_for_update(of=Student, nowait=True).filter(Student.id == 122).first()
user.type -= 1
db.session.commit()
Om FOR UPDATE
om goed te werken, allemaal betrokken transacties die de rij willen bijwerken, moeten deze gebruiken.
In uw voorbeeld gebruikt sessie 2 geen with_for_update
. Omdat je het niet hebt verteld om FOR UPDATE
te gebruiken , het is gratis om de oude waarde van de rij te lezen (aangezien de nieuwe waarde nog niet is vastgelegd en vergrendelingen pure lezers niet blokkeren), deze vervolgens in het geheugen te wijzigen en deze vervolgens terug te schrijven.
Als u FOR UPDATE
. niet wilt gebruiken overal waar u een rij leest met de bedoeling deze te wijzigen, kunt u in plaats daarvan isolation level serializable
gebruiken overal. Als je dat echter doet, wordt het misschien niet geblokkeerd, maar lijkt het eerder te slagen tot de commit, waarna serialisatiefouten ontstaan die moeten worden opgevangen en afgehandeld.
Opmerking: Je pre-edit-voorbeeld had moeten werken aangezien beide sessies waren gelabeld met with_for_update
.