Использование консультативных блокировок для координации активности базы данныхPython

Программы на Python
Anonymous
Использование консультативных блокировок для координации активности базы данных

Сообщение Anonymous »

У меня есть несколько разных заданий, которые могут выполняться в течение дня для чтения данных из разных источников и обновления моей базы данных.
Я хочу убедиться, что два задания не пытаются обновить базу данных одновременно. Для достижения этой цели я использую консультативные блокировки на уровне сеанса Postgres. Когда задание запускается, оно создает сеанс и пытается получить блокировку на уровне сеанса. Если он не может получить блокировку (поскольку другое задание уже удерживает эту блокировку), он завершает работу.
Этот код выглядит примерно так:

Код: Выделить всё

with sessionmaker(engine)() as session:
result = session.execute(
select(func.pg_try_advisory_lock(SOME_INTEGER))
)
success = next(result)[0]
if not success:
sys.exit(1)
# at this point we have acquired the lock
# do the work
В процессе тестирования и разработки я обнаружил, что после получения блокировки вызов session.commit() также снимет рекомендательную блокировку, чего я не хочу.
Чтобы обойти эту проблему, я создаю два сеанса:

Код: Выделить всё

with sessionmaker(engine)() as lock_session, sessionmaker(engine)() as work_session:
А затем я использую lock_session только для управления рекомендательной блокировкой и никогда не вызываю commit() в этом сеансе. work_session используется для выполнения фактической работы по обновлению данных.
Это работает, но выглядит как уродливый хак. Могу ли я сделать что-то лучше?

Вернуться в «Python»