sql >> Base de Datos >  >> RDS >> PostgreSQL

SQLAlchemy with_for_update ¿el bloqueo de filas no funciona?

Las 2 sesiones deberían verse así:

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

y

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

Para FOR UPDATE para que funcionen correctamente, todos las transacciones involucradas que tienen la intención de actualizar la fila deben usarla.

En su ejemplo, la sesión 2 no usa with_for_update . Ya que no le dijiste que usara FOR UPDATE , es libre de leer el valor anterior de la fila (dado que el nuevo valor aún no se ha confirmado y los bloqueos no bloquean lectores puros), luego modificar ese valor en memoria y luego escribirlo de nuevo.

Si no desea utilizar FOR UPDATE en todas partes donde lea la fila con la intención de cambiarla, podría usar isolation level serializable En todas partes. Sin embargo, si lo hace, es posible que las cosas no se bloqueen, sino que parecerán tener éxito hasta la confirmación, y luego generarán errores de serialización que deberán detectarse y solucionarse.

Nota: Su ejemplo de edición previa debería haber funcionado ya que ambas sesiones estaban etiquetadas con with_for_update .