PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

SQLAlchemy with_for_update Zeilensperrung funktioniert nicht?

Die 2 Sitzungen sollten wie folgt aussehen:

user = Student.query.with_for_update(of=Student, nowait=True).filter(Student.id == 122).first()
user.type = 1
db.session.commit()

und

user = Student.query.with_for_update(of=Student, nowait=True).filter(Student.id == 122).first()
user.type -= 1
db.session.commit()

Für FOR UPDATE richtig funktionieren, alle Beteiligte Transaktionen, die die Zeile aktualisieren möchten, müssen sie verwenden.

In Ihrem Beispiel verwendet Sitzung 2 with_for_update nicht . Da Sie ihm nicht gesagt haben, dass es FOR UPDATE verwenden soll , ist es frei, den alten Wert der Zeile zu lesen (da der neue Wert noch nicht festgeschrieben wurde und Sperren keine reinen Leser blockieren), dann diesen In-Memory-Wert zu ändern und ihn dann zurückzuschreiben.

Wenn Sie FOR UPDATE nicht verwenden möchten Überall dort, wo Sie row mit der Absicht lesen, sie zu ändern, könnten Sie stattdessen isolation level serializable verwenden überall, überallhin, allerorts. Wenn Sie dies jedoch tun, blockieren die Dinge möglicherweise nicht, sondern scheinen bis zum Commit erfolgreich zu sein, und werfen dann Serialisierungsfehler aus, die abgefangen und behandelt werden müssen.

Hinweis: Ihr Vorbearbeitungsbeispiel hätte funktionieren müssen, da beide Sitzungen mit with_for_update gekennzeichnet waren .