Что делает Postgres, когда BEGIN запускается для соединения в режиме автоматической фиксации?

Я пытаюсь лучше понять концепцию "автоматической фиксации" при работе с подключением Postgres (psycopg). Допустим, у меня есть свежее соединение, установите его уровень изоляции ISOLATION_LEVEL_AUTOCOMMIT, затем запустите этот SQL напрямую, без использования методов начала / отката курсора (в качестве упражнения; не говоря, что я действительно хочу это сделать):

INSERT A
INSERT B
BEGIN
    INSERT C
    INSERT D
ROLLBACK

Что происходит с INSERTs C & D?

Является ли autocommit чисто внутренним параметром в psycopg, который влияет на то, как он выдает BEGINs? В этом случае вышеупомянутый SQL не подвержен уязвимости; ВСТАВКИ A & B фиксируются, как только они сделаны, в то время как C & D выполняются в транзакции и откатываются. На каком уровне изоляции выполняется транзакция?

Или autocommit реальная настройка на самом соединении? В таком случае, как это влияет на обработку BEGIN? Это игнорируется или переопределяет параметр автокоммит для фактического запуска транзакции? На каком уровне изоляции выполняется транзакция?

Или я полностью вне цели?

3 ответа

Решение

Режим автоматической фиксации означает, что каждый оператор неявно начинает и заканчивает транзакцию.

В вашем случае, если автокоммит выключен:

  • Клиент неявно начнет транзакцию для первого оператора
  • BEGIN выдаст предупреждение о том, что транзакция уже запущена
  • ROLLBACK откатит все четыре утверждения

Когда автокоммит включен, только c а также d откатывается.

Обратите внимание, что PostgreSQL не имеет внутреннего AUTOCOMMIT поведение с 8.0: все функции автоматической фиксации зависят от клиентов.

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

В вашем примере A и B будут зафиксированы, C и D будут откатаны.

Когда autocommit включен, psycopg просто отправляет все на сервер PostgreSQL, не пытаясь управлять транзакцией за вас. Если вы не используете BEGIN/COMMIT/ROLLBACK, то каждый вызов.execute() немедленно выполняется и фиксируется. Вы можете сделать свое собственное управление транзакциями, выполнив команды BEGIN/COMMIT/ROLLBACK. Очевидно, что в режиме автоматической фиксации вы не можете вызывать conn.commit() или conn.rollback(), потому что psycopg не отслеживает транзакции, а просто отправляет все, что вы.execute(), прямо в бэкэнд.

В вашем примере A и B будут зафиксированы, C и D будут откатаны.

Другие вопросы по тегам