PostgreSQL Error 25P01 no_active_sql_transaction: Причины и Решение
- В технологическом журнале 1С или логах PostgreSQL фиксируется ошибка
ERROR: 25P01: no active sql transactionили предупреждениеWARNING: there is no transaction in progress. - Сбой выполнения транзакционных цепочек в прикладном коде при попытке выполнить
COMMITилиROLLBACK. - Аварийный разрыв сессий при работе через PgBouncer в режиме
pool_mode = statement. - В 1С:Предприятие транзакция завершается с ошибкой «В этой транзакции уже происходили ошибки» либо «Ошибка блокировки транзакции».
1. Анализ журнала PostgreSQL
Включите расширенное логирование сессий в postgresql.conf, чтобы отследить последовательность команд клиента:
log_statement = 'all'
log_min_messages = 'warning'
log_line_prefix = '%m [%p] %q%u@%d client=%h '
Перечитайте конфигурацию:
SELECT pg_reload_conf();2. Проверка режима работы PgBouncer / Odyssey
Если используется пул соединений, убедитесь, что для приложений с длительными транзакциями (например, 1С:Предприятие или фреймворки с ручным управлением транзакциями) установлен режим пула transaction или session, но ни в коем случае не statement:
# /etc/pgbouncer/pgbouncer.ini
[databases]
enterprise_db = host=127.0.0.1 port=5432 dbname=enterprise_db pool_mode=transaction
[pgbouncer]
pool_mode = transaction
server_reset_query = DISCARD ALL
3. Корректировка логики в коде 1С / SQL-скриптах
Ошибка возникает, когда клиент посылает COMMIT/ROLLBACK без предварительного открытия блока BEGIN, либо после того, как сервер автоматически закрыл транзакцию по таймауту:
-- Некорректно (вызовет 25P01 при повторном завершении):
COMMIT;
-- Корректный паттерн в SQL:
DO $$
BEGIN
-- Логика обработки
END $$;
4. Проверка таймаутов транзакций на стороне СУБД
Если фоновые процессы 1С долго удерживают транзакцию в состоянии ожидания, сервер может принудительно прервать ее по таймауту:
ALTER SYSTEM SET idle_in_transaction_session_timeout = '60s';
ALTER SYSTEM SET statement_timeout = '120s';
SELECT pg_reload_conf();
Частые вопросы (FAQ)
Что именно означает ошибка 25P01 (no_active_sql_transaction)?
Код 25P01 сигнализирует о том, что клиентское приложение (или драйвер) отправило команду управления транзакцией (COMMIT, ROLLBACK, PREPARE TRANSACTION), когда соединение уже находилось вне транзакционного контекста (в неявном режиме autocommit).
Почему эта ошибка массово возникает при использовании PgBouncer?
В режиме pool_mode = statement каждый оператор отправляется в произвольное серверное соединение. Команда BEGIN уходит на один серверный бэкенд, а последующий COMMIT — на другой, где транзакция не открывалась, вызывая ошибку 25P01.
Влияет ли ошибка 25P01 на целостность данных в базе 1С?
Сама по себе ошибка сигнализирует о рассинхронизации состояния клиента и сервера. Если она возникла при попытке COMMIT, это значит, что транзакция фактически не была зафиксирована, и выполненные изменения не сохранились.
Как воспроизвести ошибку 25P01 в psql для проверки логики мониторинга?
Достаточно подключиться к базе через psql и отправить команду COMMIT или ROLLBACK без предварительного вызова BEGIN. В логах появится статус 25P01 / WARNING: there is no transaction in progress.