在 Postgres/SQLAlchemy 上锁定添加具有特定外键 ID 的行
Lock Adding rows with a specific Foreign Key ID on Postgres/SQLAlchemy
假设我有一个与此类似的表格:
PERSON:
id | person_name
ITEM:
id | name | person_id
项目 person_id 是对人的 FK。
我有一个操作,可以将项目批量添加给一个人。但我想确保没有其他进程在不阻塞整个人的情况下同时向此人添加项目 table。
有没有办法在 Postgres 中实现这一点?最好使用 Python SQLalchemy?
来完成此代码
只需锁定特定人员即可防止其他会话插入引用该人员的项目。
select * from person where id=? for update
我想你想通过 Query.with_for_update
使用 SELECT FOR UPDATE
。只是一个警告,尽管您必须小心以始终以相同的顺序和相同的方式锁定,否则您可以轻松锁定线程。 IE。不要在一个代码区域锁定 table A 然后锁定 table B 并在另一个代码区域锁定 table B 然后 table A 因为它可能导致死锁.
# Other calls to SELECT FOR UPDATE will BLOCK when they try to lock this person
person = session.query(Person).with_for_update().filter(Person.id == 5).first()
# Update person items here
for item in person.items[0:3]:
session.delete(item)
session.commit()
https://www.postgresql.org/docs/9.0/sql-select.html#SQL-FOR-UPDATE-SHARE
假设我有一个与此类似的表格:
PERSON:
id | person_name
ITEM:
id | name | person_id
项目 person_id 是对人的 FK。
我有一个操作,可以将项目批量添加给一个人。但我想确保没有其他进程在不阻塞整个人的情况下同时向此人添加项目 table。
有没有办法在 Postgres 中实现这一点?最好使用 Python SQLalchemy?
来完成此代码只需锁定特定人员即可防止其他会话插入引用该人员的项目。
select * from person where id=? for update
我想你想通过 Query.with_for_update
使用 SELECT FOR UPDATE
。只是一个警告,尽管您必须小心以始终以相同的顺序和相同的方式锁定,否则您可以轻松锁定线程。 IE。不要在一个代码区域锁定 table A 然后锁定 table B 并在另一个代码区域锁定 table B 然后 table A 因为它可能导致死锁.
# Other calls to SELECT FOR UPDATE will BLOCK when they try to lock this person
person = session.query(Person).with_for_update().filter(Person.id == 5).first()
# Update person items here
for item in person.items[0:3]:
session.delete(item)
session.commit()
https://www.postgresql.org/docs/9.0/sql-select.html#SQL-FOR-UPDATE-SHARE