#20571: Using savepoints within transaction.atomic() can result in the entire
transaction being incorrectly and silently rolled back
-------------------------------------+-------------------------------------
Reporter: lamby | Owner: nobody
Type: | Status: new
Cleanup/optimization | Version:
Component: Documentation | 1.6-alpha-1
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by lamby):
Replying to [comment:2 aaugustin]:
> Technically, the inner block in the example above is strictly equivalent
to:
>
> {{{
> with transaction.atomic():
> User.objects.create(pk=user.pk)
> }}}
Yes, although one still needs to catch the DatabaseError to be literally
identical. :)
> I'm in favor of the second solution because I still have to see a use
case that isn't covered by `transaction.atomic()`. There aren't many
patterns for using savepoints in an application.
Just for clarity: I assume here you mean there aren't many patterns for
using savepoints *that are not also covered by using transaction.atomic*.
> I wonder if savepoint_commit() and savepoint_rollback() could just mark
the transaction block as "correct" again. Wouldn't this solve the problem?
No. That's too blunt as there is no way to know we are rolling back to a
savepoint that results in a clean block. I'm not explaining that very
well, so here's an untested example:
{{{
with transaction.atomic():
s1 = transaction.savepoint()
try:
User.objects.create(pk=user.pk)
except DatabaseError:
# block now correctly marked as requiring rollback
s2 = transaction.savepoint()
# [..]
transaction.savepoint_rollback(s2)
# Oops. Assuming your solution, the block would now be incorrectly
# marked as *not* requiring rollback even though it is required
# due to the User.objects.create failure. We would only be able to
# mark the block as clean if we rolled back to s1, but we have no
# way of knowing that.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/20571#comment:4>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/063.b2bfbe69ed6065ed92bdd79be672b33e%40djangoproject.com?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.