Как стать автором
Обновить

Комментарии 9

Два классических замечания к новичковым попыткам начать использовать транзакции:

Во-первых, Exception ловит только половину возможных причин, по которым выполнение кода может быть прервано.

Во-вторых, обеспечить целостность данных в случае ошибки - это, конечно, хорошо. Но вот замалчивать ошибку при этом не стоит. Откатив транзакцию, надо проинформировать об ошибке программиста.

Поэтому

} catch (\Throwable $e) {
    // Если произошла ошибка, отменяем транзакцию
    $connection->rollbackTransaction();
    throw $e;
}

Понятно, что от бессмысленного лепета "'Ошибка в процессе сохранения данных." толку мало, но это, как я понимаю, издержки битрикса. Возможно, когда-нибудь он научится сам кидать нормальные исключения. А пока хоть это пусть выдаёт.

В статье акцент сделан на транзакциях, чтобы упростить и подчеркнуть основную тему. Поэтому обработка исключений представлена более простым образом.

В реальных проектах, конечно же, рекомендуется более детально обрабатывать ошибки. Ваши замечания в этом смысле абсолютно верные

Если после startTransaction произойдет непредвиденное завершение работы приложения и до rollbackTransaction мы не доберёмся, что произойдет? Будет ли произведен автоматический откат при следующей инициализации ядра Bitrix?

Скорее при прекращении текущего соединения.
MySQL innodb автоматически откатывает все незакомиченные изменения.

Это, кстати, хорошее замечание, которое как бы намекает, что в общем случае заключать транзакцию в try-catch в принципе и не нужно - транзакция и так откатится при закрытии соединения. Но учитывая, что явное лучше неявного, то традиционно мы это делаем. Тем более что некоторых обстоятельствах (персистентное соединение с БД, например) надо все-таки, хотя бы попытаться.

Кстати, собрался прочитать текст по ссылке. Тема "вложенности" транзакций в статье не раскрыта от слова совсем.

Я ещё вчера очень удивился, поскольку при чтении складывается полное впечатление, будто в битрикс добавили поддержку транзакций вообще, а раньше их не было. А слово "вложенные" просто вкралось по ошибке. И только прочитав документацию, понял, о чем речь.

Сама по себе поддержка транзакций в битриксе была давно (что и неудивительно, поскольку там явно растут ноги из PDO). А появилась поддержка именно "вложенных" транзакций, собранная из SAVEPOINT и палок, что позволило использовать транзакции не только в "вызывающем (конечном) сценарии" (что бы это не значило), "но и в API". В то время как ранее

...могла сложиться ситуация, когда конечный сценарий открывает транзакцию, вызываемый API тоже открывает свою транзакцию, в итоге все коммиты и роллбеки перемешиваются непредсказуемым образом.

То есть новость должна звучать не "В битриксе появилась поддержка транзакций", а "теперь транзакции можно использовать как в конечном приложении, так и в API".

складывается полное впечатление, будто в битрикс добавили поддержку транзакций вообще

Изначально, писав статью, сам так подумал. Т.к сам использовать транзакции стал на практике не так давно.
Уже после выхода статьи, осознал ошибку в терминологии. Постарался дописать и более подробно раскрыть тему вложенных транзакций.

Статья про транзакции, а не про вложенность. Вложенность работает так под капотом:

$db = \Bitrix\Main\Application::getConnection();

try
{
    // START TRANSACTION
    $db->startTransaction();

        // SAVEPOINT 1
        $db->startTransaction();

            // SAVEPOINT 2
            $db->startTransaction();
            
            // -
            $db->commitTransaction();
            
        // ROLLBACK TO SAVEPOINT 1 (внутри кидает TransactionException)
        $db->rollbackTransaction();

    // DON'T EXECUTE
    $db->commitTransaction();
}
catch (\Bitrix\Main\DB\TransactionException $e)
{
    // ROLLBACK
    $db->rollbackTransaction();
}
catch (Throwable $e)
{
    // ROLLBACK or ROLLBACK TO SAVEPOINT *
    $db->rollbackTransaction();
    
    throw $e;
}

Спасибо за ценные замечания!
Постарался дополнить статью, убрать использование неправильного термина и раскрыть подробнее сами вложенные транзакции.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации