Ошибка PostgreSQL 0B000: invalid_transaction_initiation — исправление
- Ошибка
ERROR: invalid transaction initiation (SQLSTATE 0B000)в логах СУБД. - Клиентское приложение или сервер 1С получает отказ при вызове команд управления транзакциями (
START TRANSACTION,BEGIN). - Сбои возникают при использовании пулеров соединений (PgBouncer, Odyssey) в режиме Transaction Pooling при некорректной передаче состояния сессии.
1. Анализ проблемы с вложенными транзакциями
PostgreSQL не поддерживает команду START TRANSACTION внутри уже активной транзакции (в отличие от некоторых других СУБД). Вместо повторного вызова BEGIN используйте точки сохранения (Savepoints):
-- Неверно:
BEGIN;
START TRANSACTION; -- Вызовет ошибку 0B000 или предупреждение 25001
-- Корректно:
BEGIN;
SAVEPOINT my_savepoint;
-- Операции...
ROLLBACK TO SAVEPOINT my_savepoint;
COMMIT;2. Проверка и настройка PgBouncer
Если используется PgBouncer в режиме pool_mode = transaction, убедитесь, что клиентские приложения не отправляют команды управления сессионными параметрами в транзакционном блоке. Отредактируйте /etc/pgbouncer/pgbouncer.ini:
[pgbouncer]
pool_mode = transaction
server_reset_query = DISCARD ALL
ignore_startup_parameters = extra_float_digits, application_name3. Очистка залипших транзакций в кластере 1С
SELECT pid, usename, state, query_start, age(now(), query_start), query
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY age(now(), query_start) DESC;Принудительное завершение блокирующей сессии:
SELECT pg_terminate_backend(12345); Частые вопросы (FAQ)
Почему 1С генерирует ошибку инициализации транзакции при работе через PgBouncer?
Платформа 1С:Предприятие требует поддержания сессионного состояния (Session State) и временных таблиц. Использование режима Transaction Pooling в PgBouncer не поддерживается сервером 1С — необходимо использовать pool_mode = session.
В чем отличие 0B000 от 25001 (active_sql_transaction)?
25001 сигнализирует о попытке вызвать BEGIN внутри уже открытой транзакции, тогда как 0B000 указывает на вызов недопустимых транзакционных характеристик или сбой протокола инициализации транзакции.
Как автоматически прерывать сессии, зависшие в idle in transaction?
Установите параметр idle_in_transaction_session_timeout в postgresql.conf (например, idle_in_transaction_session_timeout = '60s').
Может ли 2PC (Two-Phase Commit) вызывать ошибку 0B000?
Да, при попытке выполнить PREPARE TRANSACTION или COMMIT PREPARED вне корректного контекста распределенной транзакции.