Блокировка стола с помощью ACCESS EXCLUSIVE с помощью psycopg2 - PullRequest
0 голосов
/ 14 мая 2018

Я пытаюсь явно заблокировать таблицу с помощью psycopg2 с помощью Django & Heroku, поэтому к ней пока никто другой сервер / работник не обращается.

Я прочитал, что ACCESS EXCLUSIVE делает именно то, чтоЯ нуждаюсь.Тем не менее, я нашел только объяснения о том, когда он вызывается автоматически (с DROP TABLE, VACUUM FULL и т. Д. ; но я не знаю, как я могу вызвать его явно, чтобы заблокировать таблицу вмоя воля.

Я попробовал следующее:

 with SQL().con2db() as conn:

   cur = conn.cursor()

    lock_query = 'ACCESS EXCLUSIVE {tbl_name}'.format(tbl_name=tbl_name)
    cur.execute(lock_query, )

    #do whatever

    cur.close()

Но я получаю сообщение об ошибке:

psycopg2.ProgrammingError: syntax error at or near "ACCESS"
LINE 1: ACCESS EXCLUSIVE table_name

Как мне этого добиться?

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Чтобы явно заблокировать таблицу, используйте оператор SQL LOCK.

Поскольку блокировки удерживаются только до конца транзакции базы данных, вы должны явно запустить и завершить транзакцию.

Поскольку это существенно влияет на параллелизм, вам следует подумать, не существует ли лучшего способа решения вашей проблемы.

0 голосов
/ 14 мая 2018

После некоторого дальнейшего исследования я нашел этот пост , в котором говорится о консультативных блокировках:

Консультативные блокировки

Postgres предоставляет средства для создания блокировок, которые имеют определяемые приложением значения. Это так называемые консультативные блокировки, потому что система не навязывает их использование - дело за приложением используйте их правильно.

Существует два способа получения консультативной блокировки в Postgres: на сессии уровень или на уровне транзакции. После получения на уровне сеанса консультативная блокировка удерживается до тех пор, пока явно не будет освобождена или сеанс не закончится В отличие от стандартных запросов на блокировку, запросы на блокировку на уровне сеанса делают не соблюдайте семантику транзакции: блокировка, полученная во время транзакции откат будет по-прежнему удерживаться после отката, и аналогично разблокировка эффективна, даже если вызывающая транзакция не удается позже. Блокировка может быть получена много раз процесс; для каждого выполненного запроса блокировки должен быть соответствующий запрос на разблокировку до фактического снятия блокировки. Транзакция уровня запросы блокировки, с другой стороны, ведут себя больше как обычная блокировка запросы: они автоматически освобождаются в конце транзакции, и нет явной операции разблокировки. Это поведение часто более удобно, чем поведение на уровне сеанса для кратковременное использование консультативного замка. Сессионный уровень и запросы блокировки на уровне транзакции для того же консультативного идентификатора блокировки будут блокировать друг друга ожидаемым образом. Если сессия уже проводится данная консультативная блокировка, дополнительные запросы от нее всегда будут успешными, даже если другие сеансы ожидают блокировки; это утверждение верно независимо от того, находится ли существующая блокировка блокировки и новый запрос в уровень сеанса или уровень транзакции. Полный список функций для Управляющие консультативные блокировки можно найти в документации .

...

-- Transaction 1
BEGIN;

SELECT pg_advisory_xact_lock(1);
-- Some work here

Я не уверен, как именно это работает, так как я не указываю таблицу, которую хочу заблокировать, но, похоже, она выполняет свою работу.

with SQL().con2db() as conn:

    cur = conn.cursor()

    lock_query = 'SELECT pg_advisory_xact_lock(1);'
    cur.execute(lock_query, )

    #do whatever

    cur.close()

Любые дальнейшие объяснения, чтобы лучше понять это или альтернативные подходы, более чем приветствуются.

...