Какой уровень транзакции у функций PL/pgSQL?
Из документации Постгерса: "В функции на PL/pgSQL нельзя использовать COMMIT. Функция работает в рамках некоторой внешней транзакции, и поэтому COMMIT будет означать прекращение выполнения функции."
Пользуясь гуглом и методом научного тыка, я понял, что код, исполняемый функцией в Постгресе атомарен. Явно объявить в нём транзакцию мы также не можем, получаем ошибку.
Подскажите, пожалуйста:
- Если можно в деталях, как вообще работает транзакционность в функциях PL/pgSQL?
- Конкретно интересующий меня вопрос: какой уровень изоляции у этих неявных "внешних" транзакций? Интересует, в первую очередь, с точки зрения видимости изменений из параллельных транзакций и блокировок, накладываемых на строки (если Постгрес так делает, с концепцией MVCC знаком поверхностно).
Ответы (1 шт):
Так же как и любой запрос:
- если запрос пришёл при уже открытой внешней транзакции - работает в этой транзакции с теми параметрами транзакции, с которыми та открыта
- если явной транзакции не открыто, то открываем неявно транзакцию перед началом обработки запроса и после окончания запроса эту транзакцию коммитим.
Ну а чтобы вызвать функцию, вам нужно прислать запрос. Таким образом, вызов функции всегда находится внутри внешней транзакции, открытой явно либо же неявно.
Уровень изоляции, если не был запрошен явно при открытии транзакции, используется указанный в настройке default_transaction_isolation
(обычно read committed). Всё поведение в транзакции по блокировкам, видимости MVCC снимка данных - по обычным правилам. Из специфики PL/pgSQL разве что можно упомянуть неявные savepoint'ы
при использовании EXCEPTION
блоков, что довольно-таки не бесплатно.