PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

O bloqueio de linha SQLAlchemy with_for_update não está funcionando?


As 2 sessões devem ficar assim:
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()

Para FOR UPDATE para funcionar corretamente, todos transações envolvidas que pretendem atualizar a linha precisam usá-la.

No seu exemplo, a sessão 2 não está usando with_for_update . Como você não disse para usar FOR UPDATE , é livre para ler o valor antigo da linha (já que o novo valor ainda não foi confirmado e os bloqueios não bloqueiam leitores puros), modifique-o nesse valor na memória e escreva-o de volta.

Se você não quiser usar FOR UPDATE em todos os lugares em que você lê a linha com a intenção de alterá-la, você pode usar isolation level serializable em todos os lugares. No entanto, se você fizer isso, as coisas podem não bloquear, mas parecerão bem-sucedidas até a confirmação e, em seguida, lançarão erros de serialização que precisarão ser capturados e tratados.

Observação: Seu exemplo de pré-edição deve ter funcionado, pois ambas as sessões foram rotuladas com with_for_update .