Что делает Postgres, когда BEGIN запускается по соединению в режиме автоматической фиксации?
-
21-09-2019 - |
Вопрос
Я пытаюсь лучше понять концепцию "автоматической фиксации" при работе с подключением Postgres (psycopg).Допустим, у меня новое соединение, установите для него уровень изоляции ISOLATION_LEVEL_AUTOCOMMIT, затем запустите этот SQL напрямую, без использования методов запуска курсора / отката (в качестве упражнения;не говорю, что я действительно хочу это сделать):
INSERT A
INSERT B
BEGIN
INSERT C
INSERT D
ROLLBACK
Что происходит со вставками C & D?
Является ли autocommit чисто внутренней настройкой в psycopg, которая влияет на то, как начинаются проблемы?В этом случае приведенный выше SQL не будет изменен;Вставки A и B фиксируются сразу по завершении, в то время как C и D запускаются в транзакции и откатываются.На каком уровне изоляции выполняется эта транзакция?
Или автоматическая фиксация - это реальная настройка самого соединения?В таком случае, как это влияет на обработку BEGIN?Игнорируется ли он или переопределяет параметр автоматической фиксации, чтобы фактически запустить транзакцию?На каком уровне изоляции выполняется эта транзакция?
Или я совершенно не попал в цель?
Решение
Режим автоматической фиксации означает, что каждый оператор неявно начинает и завершает транзакцию.
В вашем случае, если функция автоматической фиксации отключена:
- Клиент неявно запустит транзакцию для первого оператора
- Тот Самый
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 будут откачены.