PostgreSQL Error 25P02 in_failed_sql_transaction: Решение проблемы
- Ошибка в приложении:
ERROR: 25P02: current transaction is aborted, commands ignored until end of transaction block. - В 1С:Предприятие падает проведение документов с сообщением «Ошибка транзакции СУБД: транзакция отменена».
- Все последующие запросы внутри текущей сессии блокируются до отправки явного
ROLLBACK. - В технологическом журнале 1С фиксируются события
DBPOSTGRSсо статусом ошибки и последующим аварийным завершением серверного контекста.
1. Поиск первопричины (первичного сбоя в транзакции)
Ошибка 25P02 является вторичной. Она указывает, что ранее внутри этого же блока транзакции произошла другая ошибка (нарушение foreign key, дедлок, дубликат уникального ключа, деление на ноль), которую клиент проигнорировал и попытался отправить следующий запрос.
Найдите первоначальную ошибку в логе PostgreSQL:
grep -B 5 -A 2 "25P02" /var/log/postgresql/postgresql-*.log2. Использование точек сохранения (Savepoints)
Если бизнес-логика предполагает обработку потенциально сбойных операторов внутри одной транзакции, оборачивайте их в SAVEPOINT:
BEGIN;
INSERT INTO accounts VALUES (1, 'Alice');
SAVEPOINT my_savepoint;
-- Запрос, который может упасть:
INSERT INTO accounts VALUES (1, 'Duplicate'); -- Вызовет 23505 (unique_violation)
-- При возникновении ошибки откатываемся к точке сохранения:
ROLLBACK TO SAVEPOINT my_savepoint;
-- Продолжаем транзакцию без ошибки 25P02:
INSERT INTO accounts VALUES (2, 'Bob');
COMMIT;
3. Проверка технологического журнала 1С:Предприятие
Настройте сбор логов logcfg.xml для фиксации контекста исходной ошибки:
<log location="/var/log/1c/logs" history="24">
<event>
<eq property="name" value="DBPOSTGRS"/>
<eq property="failed" value="true"/>
</event>
<property name="all"/>
</log>
4. Корректировка параметров пулеров и драйверов
Убедитесь, что коннекторы (psycopg2, npgsql, JDBC) настроены на автоматический откат транзакции в блоках перехвата исключений (try/except, try/catch):
# Пример паттерна на Python / psycopg2
try:
cursor.execute("SELECT 1/0;")
except Exception:
conn.rollback() # Обязательный откат перед следующими запросами
Частые вопросы (FAQ)
Почему PostgreSQL блокирует все команды после первой ошибки внутри транзакции?
PostgreSQL строго следует стандарту ANSI SQL: если один из операторов внутри атомарного блока завершился сбоем, состояние базы признается неконсистентным до тех пор, пока клиент явно не откатит транзакцию (ROLLBACK) или не вернется к точке сохранения (ROLLBACK TO SAVEPOINT).
Чем поведение PostgreSQL в этом случае отличается от MySQL / MS SQL?
В MS SQL Server и MySQL (InnoDB) некоторые некритические ошибки позволяют продолжать выполнение транзакции без обязательного отката всего блока. В PostgreSQL любая ошибка переводит транзакцию в состояние ABORTED.
Как исправить эту ошибку в конфигурациях 1С?
Необходимо локализовать исходное исключение в модуле проведения документа, обернуть сбойный алгоритм в конструкцию 'Попытка - Исключение' и гарантировать, что при ошибке вызывается 'ОтменитьТранзакцию()', а не продолжается выполнение запросов к СУБД.
Помогает ли перезапуск службы PostgreSQL избавиться от 25P02?
Нет, перезапуск СУБД не устраняет проблему, так как ошибка вызвана логикой клиентского кода или сценарием обработки транзакций в приложении.