Почему этот внутренний атомарный блок не откатывается в коде пользовательского представления viewflow

Я создал это пользовательское представление процесса создания, чтобы добавить электронную почту вошедшего пользователя в сохраненный объект, я также добавил блок транзакций, чтобы при неудаче следующего шага (внутри оператора self.activation_done()) он откатывал изменения в БД внутри form_valid() и затем отображал ошибку в шаге запуска, поэтому новый экземпляр процесса не сохраняется.

from django.core.exceptions import ValidationError
from django.db import transaction
from django.http import HttpResponseRedirect
from viewflow.flow.views import CreateProcessView, StartFlowMixin


class StarterEmailCreateProcessView(CreateProcessView):
    """
    Sets the user email to the process model
    """
    def form_valid(self, form, *args, **kwargs):
        """If the form is valid, save the associated model and finish the task."""
        try:
            with transaction.atomic():
                super(StartFlowMixin, self).form_valid(form, *args, **kwargs)
                # begin of setting requester email
                # https://github.com/viewflow/viewflow/issues/314
                self.object.requester_email = self.request.user.email
                self.object.save()
                # end of setting requester email
                self.activation_done(form, *args, **kwargs)
        except Exception as ex:
            form.add_error(None, ValidationError(str(ex)))
            return self.form_invalid(form, *args, **kwargs)
        return HttpResponseRedirect(self.get_success_url())

Согласно документации Django, исключение, возникшее внутри транзакции, откатывается

enter image description here

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

Без выхода self.lock.__enter__() выглядел подозрительно, поэтому я изменил его на следующий, и он откатился, как и ожидалось

        with transaction.atomic(savepoint=True):
            signals.task_started.send(sender=self.flow_class, process=self.process, task=self.task)

            self.process.save()

            lock_impl = self.flow_class.lock_impl(self.flow_class.instance)
            self.lock = lock_impl(self.flow_class, self.process.pk)
            # self.lock.__enter__()
            with self.lock:
                self.task.process = self.process
                self.task.finished = now()
                self.task.save()

                signals.task_finished.send(sender=self.flow_class, process=self.process, task=self.task)
                signals.flow_started.send(sender=self.flow_class, process=self.process, task=self.task)

                self.activate_next()

@kmmbvnr не могли бы вы проверить? Будут ли какие-либо нежелательные последствия после этого изменения?

Вернуться на верх