#python #postgresql #sqlalchemy
Вопрос:
Допустим, у меня есть таблица, похожая на эту:
PERSON:
id | person_name
ITEM:
id | name | person_id
Элементы person_id-это FK для человека.
У меня есть операция, которая добавляет товары оптом к человеку. Но я хочу убедиться, что никакие другие процессы не добавляют элементы одновременно к этому человеку, не блокируя всю таблицу person.
Есть ли способ достичь этого в Постгресе? И лучше код для достижения этой цели с помощью Python SQLAlchemy?
Ответ №1:
Я думаю, вы хотите использовать SELECT FOR UPDATE
via Query.with_for_update
. Просто предупреждение, хотя вы должны быть осторожны, чтобы всегда блокировать в одном и том же порядке и одним и тем же способом, иначе вы можете легко заблокировать свои потоки. Т. е. Не блокируйте таблицу A, затем заблокируйте таблицу B в одной области кода и заблокируйте таблицу B, а затем таблицу 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
Комментарии:
1. Большое вам спасибо 🙂 это как раз то, что мне было нужно
Ответ №2:
Просто блокировка конкретного пользователя предотвратит вставку другими сеансами элементов, ссылающихся на этого человека.
select * from person where id=? for update