Code-review процедуры "Перевод платежа в ошибку". Анализ
Задача: см пост вторника
Анализ
С первого взгляда, код вполне себе невинен. Отрабатываются основные ситуации:
1️⃣ статус платежа не подходящий для изменений (if v_status != c_active then).
2️⃣ когда платежа нет (when no_data_found then);
Однако в обработке каждой ситуации заложена архитектурная ошибка 🤷♂️
1️⃣ Проверка статуса
БД, в принципе, многосессионная среда. Это API для работы с отдельной сущностью. Подобные обертки в основном реализуются не в DWH, в котором работа с данными выполняется в чуть более свободном режиме.
Соответственно, могут возникать ситуации, когда с одной и той же сущностью работают более чем 1 сессия. Могут возникать race condition.
Если совсем на пальцах: между тем, когда мы считали статус платежа (select status) и тем, когда мы совершаем update payment, статус мог измениться. В многосессионной среде так и будет. Разруливаются подобные проблемы - блокировками.
Первый вариант: добавить for update с опциями, которые соответствуют бизнес-задаче.
select status … for update с опциями;
Второй вариант: проверять в update статус. Если строка заблокирована, то выполнение повиснет до освобождения блокировки.
2️⃣ Обработка отсутствия платежа.
В текущей реализации - это бомба замедленного действия. Как правильно заметили в комментариях, рано или поздно будет добавлен еще один select и общий NO_DATA_FOUND на весь блок будет отрабатывать не только отсутствие платежа, но и другие запросы.
Как надо бы сделать - обернуть select, возбудить в нем пользовательское исключение и уже в общем блоке его обработать.
begin
select …
exception
when no_data_found then
raise e_payment_not_found;
end;
Итог: код не прошел code review.
—
Продолжая тему: лучше выделить функционал в отдельную процедуру типа try_lock_payment, в которой блокировать платеж, проверять его state и наличие. Т.к. api-процедур по работе с платежом более чем одна.
Подобный код пишут студенты на курсе Основы PL/SQL, в котором мы разбираем не только синтаксис и объекты, но и архитектурные принципы построения API. Старт - 12.01. Записывайтесь, пока еще, есть несколько мест 🔥
#решениезадачи #блокировки #исключения
Oracle Developer