Yii-ные beginTransaction

переопределить Yii-ные beginTransaction и commit, чтобы они работали так:
при повторном (вложенном) вызове beginTransaction транзакция не стартует, вместо нее возвращается TransactionNullObject
при повторном (вложенном) вызове commit  транзакция не будет комититься, вместо нее будет вызываться фиктивный commit -метод объекта TransactionNullObject
TransactionNullObject это реализация паттерна https://designpatternsphp.readthedocs.io/ru/latest/Behavioral/NullObject/README.html

Пример проблемы:

db->beginTransaction();
try {

    // first SQL of first transaction

    $transaction2 = Yii::app()->db->beginTransaction();
    try {
        // some SQL of second transaction
        $transaction2->commit();// тут закомитится "first SQL of first transaction" + "some SQL of second transaction"
    } catch (\Exception $exception) {
        $transaction2->rollback();
    }

    // second SQL of first transaction (если выше будет вызван $transaction2->rollback(); то этот SQL отработает и ниже мы его закомитим)

    $transaction->commit();// т.к. $transaction2->commit(); уже закомитил транзакцию, то тут будет ошибка - транзакция не начата

} catch (\Exception $exception) {
    $transaction->rollback();
}

В нашем репозитории полно подобных ситуаций и вот например одна из  них:

в классе \Gs\Office\Service\PatientDeduplication\PatientDeduplicationService есть функция updatePatientRelations (транзакция) -> updateMainPatient (вложенная транзакция) -> updateMainPatientForPatients (вложенная транзакция - третий уровень)

Решение видится в создании своего объекта NullTransaction это реализация паттерна https://designpatternsphp.readthedocs.io/ru/latest/Behavioral/NullObject/README.html

Итого, что предется переопределить:

\CDbConnection

  • beginTransaction - при повторном (вложенном) вызове транзакция не стартует, вместо нее возвращается TransactionNullObject
  • getCurrentTransaction - при повторном (вложенном) вызове возвращается TransactionNullObject

\CDbTransaction

  • commit - при повторном (вложенном) вызове транзакция не будет комититься, вместо нее будет вызываться фиктивный commit-метод объекта TransactionNullObject
  • rollback - выполняет ролбэк существующей транзакции + выбрасывает эксепшен

Подмену Yii классов можно реализовать с помощью composer-a.

Обязательным будет покрытие тестами такого функционала.


23.12.2010 11:10

Комментарии

Комментариев пока нет.


Copyrights © 2007 - 2026 YaPro.Ru