Informix не поддерживает вложенные транзакции, и поэтому при начале и завершении тразакции запросами BEGIN WORK, COMMIT WORK и ROLLBACK WORK могут возникать ошибки двух видов:
В процедурах и функциях SPL эти ошибки могут быть нормально обработаны с помощью ON EXCEPTION, но это в ряде случаев не очень удобно. Есть два метода, позволяющие узнать текущее состояние транзакции в любом запросе, скрипте или приложении.
Имеется недокументированная встроенная функция SPL intransaction, позволяющая выполнить определенные действия в зависимости от того, была ли открыта явная тразакция - например, откатить транзакцию, если она была открыта:
IF intransaction THEN . . . . ROLLBACK WORK; . . . . END IF;
Создать в базе данных новую внешнюю функцию с любым именем (например, txstate), оборачивающую функцию mi_transaction_state из Datablade API:
CREATE FUNCTION "informix".txstate() RETURNS INT EXTERNAL NAME '(mi_transaction_state)' LANGUAGE C; GRANT EXECUTE ON FUNCTION "informix".txstate() TO "public" AS "informix";
Эта функция возвращает целочисленное значение:
Теперь эту функцию можно использовать в любом запросе. Приведенный выше фрагмент можно записать как:
IF txstate() = 1 THEN . . . . ROLLBACK WORK; . . . . END IF;