Справочник системных ошибок и решений

Windows Server, Active Directory, 1С:Предприятие, СУБД, Linux, Cisco, MikroTik, Asterisk.

⚠️ Важная информация Все материалы, инструкции, команды и скрипты на сайте предоставлены исключительно в ознакомительных целях. Их применение может повлиять на работу операционной системы, программного обеспечения, баз данных, сетевого оборудования и других компонентов инфраструктуры. Перед выполнением действий создайте резервную копию и по возможности протестируйте изменения в безопасной среде. Пользователь самостоятельно оценивает риски и несет ответственность за результат. При отсутствии необходимых знаний обратитесь к квалифицированному ИТ-специалисту.

2D522 1С:Предприятие и СУБД

PostgreSQL Error 2D522 invalid_transaction_termination: Разбор ошибки

Обновлено: 26.08.2026 · Официальная документация ↗
  • Ошибка выполнения SQL: ERROR: 2D522: invalid transaction termination.
  • Сбой выполнения функций PL/pgSQL при попытке явного управления транзакциями (COMMIT или ROLLBACK).
  • Падение триггеров баз данных при попытке завершить транзакцию внутри тела триггерной функции.
  • Отказ выполнения пакетов интеграций между 1С и сторонними сервисами через вызов RPC-функций PostgreSQL.

1. Архитектурное ограничение функций в PostgreSQL

В PostgreSQL функции (созданные через CREATE FUNCTION) всегда выполняются внутри транзакционного контекста вызывающего запроса и не имеют права выполнять COMMIT или ROLLBACK. Нарушение этого правила приводит к генерации исключения 2D522.

2. Миграция с CREATE FUNCTION на CREATE PROCEDURE (PostgreSQL 11+)

Начиная с PostgreSQL 11, для поддержки управления транзакциями внутри процедурного кода были добавлены хранимые процедуры (PROCEDURE):

-- ОШИБОЧНЫЙ ВАРИАНТ (вызовет 2D522):
CREATE OR REPLACE FUNCTION bad_batch_process()
RETURNS void AS $$
BEGIN
    INSERT INTO logs VALUES ('Step 1');
    COMMIT; -- ОШИБКА 2D522!
END;
$$ LANGUAGE plpgsql;

-- ПРАВИЛЬНЫЙ ВАРИАНТ (Использование PROCEDURE):
CREATE OR REPLACE PROCEDURE good_batch_process()
LANGUAGE plpgsql AS $$
BEGIN
    INSERT INTO logs VALUES ('Step 1');
    COMMIT; -- Полностью разрешено
    
    INSERT INTO logs VALUES ('Step 2');
    ROLLBACK; -- Полностью разрешено
END;
$$;

-- Вызов процедуры:
CALL good_batch_process();

3. Ограничения процедур внутри явных транзакций и функций

Даже хранимая процедура не может выполнить COMMIT, если она вызвана внутри внешнего блока BEGIN ... COMMIT клиента или из триггера:

-- Этот вызов упадет с 2D522, если внутри процедуры есть COMMIT:
BEGIN;
CALL good_batch_process(); -- Ошибка: нельзя коммитить внутри внешней транзакции
COMMIT;

-- Корректный вызов процедур с автономными транзакциями:
CALL good_batch_process(); -- Вне явного внешнего блока BEGIN

4. Обработка исключений вместо ручного ROLLBACK

Если цель использования ROLLBACK в функции — перехват ошибок, замените его на блок EXCEPTION:

CREATE OR REPLACE FUNCTION safe_insert_data()
RETURNS boolean AS $$
BEGIN
    INSERT INTO target_table (id, data) VALUES (1, 'Test');
    RETURN true;
EXCEPTION
    WHEN unique_violation THEN
        -- Транзакция откатится к неявной точке сохранения автоматически
        RETURN false;
END;
$$ LANGUAGE plpgsql;
💡 Практика специалистов: Если вы переносите логику с Oracle Database на PostgreSQL для работы с 1С или самописными сервисами, переписывайте функции с PRAGMA AUTONOMOUS_TRANSACTION на процедуры (CALL procedure()) либо используйте dblink_exec().

Частые вопросы (FAQ)

Можно ли выполнить COMMIT внутри триггера в PostgreSQL?

Нет. Триггеры в PostgreSQL всегда работают в контексте DML-операции (INSERT/UPDATE/DELETE), являющейся частью внешней транзакции. Управление транзакциями внутри триггеров принципиально запрещено.

В чем ключевая разница между FUNCTION и PROCEDURE относительно транзакций?

Функция (FUNCTION) возвращает значение и всегда атомарна (не может управлять транзакцией). Процедура (PROCEDURE) вызывается через CALL и может содержать операторы COMMIT и ROLLBACK для пакетной обработки данных.

Почему вызов процедуры из клиента 1С через ADODB/ODBC падает с 2D522?

Многие драйверы по умолчанию открывают неявную транзакцию перед каждым вызовом. Отключите авто-транзакции в свойствах коннектора (autocommit mode = on), чтобы разрешить процедуре управлять коммитами.

Поддерживает ли PostgreSQL автономные транзакции (Autonomous Transactions) как в Oracle?

Нативно нет. Для реализации автономных транзакций в функциях используется расширение dblink или pg_background, открывающее отдельную независимую сессию к серверу.

Полезные материалы
Рекомендуем