PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

SQLAlchemy with_for_update il blocco delle righe non funziona?

Le 2 sessioni dovrebbero assomigliare a questa:

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

e

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

In ordine per FOR UPDATE per funzionare correttamente, tutti le transazioni coinvolte che intendono aggiornare la riga devono utilizzarla.

Nel tuo esempio, la sessione 2 non utilizza with_for_update . Dal momento che non gli hai detto di usare FOR UPDATE , è libero di leggere il vecchio valore della riga (poiché il nuovo valore non è stato ancora confermato e i blocchi non bloccano i lettori puri), quindi modificarlo quel valore in memoria, quindi riscriverlo.

Se non vuoi usare FOR UPDATE ovunque tu abbia letto la riga con l'intenzione di cambiarla, potresti invece usare isolation level serializable ovunque. Tuttavia, se lo fai, le cose potrebbero non bloccarsi, ma sembrerà che abbiano successo fino al commit, quindi generano errori di serializzazione che dovranno essere rilevati e gestiti.

Nota: Il tuo esempio di pre-modifica dovrebbe aver funzionato poiché entrambe le sessioni erano etichettate con with_for_update .