Задача 2в1 про исключения и транзакции
Сегодня маленько припозднился 😔
Постановка: смотрите пост вторника
Решение
1️⃣ В таблице tab1 на момент выполнения блока уже 1 строка. Вставка добавит еще одну строку.
2️⃣ Деление на ноль вызовет именованное системное исключение “деление на ноль” (ZERO_DIVIDE). Оно будет перехвачено в блоке обработки исключений - others.
3️⃣ Транзакция при этом не откатится.
Таким образом, select count(*) вернет “2”.
Правильный ответ: в буфере вывода будет - “2”
Интересно как распределились голоса 📊 Видимо, большинство уверено, что будет откат транзакции 😔
Если необходимо эмулировать откат, то надо было бы поставить savepoint перед вставкой и выполнить rollback на эту точку сохранения в секции обработки исключений.
declare
…
begin
savepoint sp1;
insert …
…
exception
when others then
rollback to sp1;
select count(*) …
end;
/
Забавно, что в PostgreSQL поведение отличается.
Поведение аналогично второму варианту - с откатом транзакции.
После begin ставится неявно точка сохранения и в случае ошибок происходит откат на эту точку. Этот код будет выводить “1”.
do $$
declare
v_cnt numeric(2);
begin
insert into tab1 values (1);
v_cnt := 1/0;
exception
when others then
select count(*) into v_cnt from tab1;
raise notice '%', v_cnt;
end
$$;
Смигрировали вы такие код с Oracle на PostgreSQL и … не заметили маааленькое различие в работе с транзакциями -> логика работы нарушилась 🤯
Если есть спецы в PG, напишите в комментариях, можно ли изменить это поведение какими-нибудь настройками?
Понравилась задачка? Палец вверх 👍
#решениезадачи #транзакции #postgresql