This is primarily a function of the DBMS.  When your operations cause a
DB-level error, the DB needs to roll back the transaction to clean up.

If you don't, you're operating on an unknown state.

Django can not control this beyond wrapping the "risky" operation in a
transaction.

Consider -- exactly what should Django do to clean up the database thrown
integrity error without a transaction point to roll back to?

--
Curtis


On 1 October 2014 11:47, Cristiano Coelho <[email protected]> wrote:

> Hello there,
>
> I have recently updated to django 1.7, from 1.5 and one of the main
> changes I had to do was to replace all deprecated
> transaction.commit_manually to transaction.atomic, so far so good.
>
> After this, I have found out that if an IntegrityError or DatabaseError
> exception happen inside a code that is decorated with @transaction.atomic
> (or inside a with transaction.atomic) and the exception is handled (not
> throwing it out from the atomic block) the whole transaction gets invalid,
> and any other database access will fail, just as described in the docs
> (silly me I didn't read them with enough depth).
>
> As mentioned in the docs, the solution is to also put the "exception
> throwing code" inside another atomic block, and catch the exception outside
> of it. I can not describe how anoying this is, compared to the old
> behaviour where I could easly decide when to commit or rollback, now I have
> to review my whole code to detect the places where a database save is
> performed and the exception is handled, and add another atomic block to it.
>
> I believe this was an issue heavily discussed with the develpers and they
> came to this as the best option, but there needs to be another easier way
> to handle this kind of issue.
> What are the complications of leaving the transaction in a correct state
> even if an operation raises a database error and the exception is handled
> silently (not thrown outside of the atomic block)? This was totally
> possible with the deprecated transaction functions, where you could do all
> your logic and just at the end handle the transaction commit or rollback,
> and didn't matter what happened inside of it. But now this is imposible,
> you need to keep a sharp eye on every database save you perform and
> surround it with another atomic block just in case it raises a database
> error exception.
>
>
> To make the issue clear, here's a sample code:
>
> First one shows what would my current code look like, where add_children()
> would raise an exception because generate_relationships() was not inside
> another atomic block.
> With the old transactions api, I could easily surround the whole code in
> another try/except, and at the very end commit or rollback, and everything
> would be fine even if generate_relationships() throws an exception, it
> would be siltently ignored.
>
> from django.db import IntegrityError, transaction
> @transaction.atomicdef viewfunc(request):
>     create_parent()
>
>     try:
>         generate_relationships()
>     except IntegrityError:
>         handle_exception()
>
>     add_children()
>
>
>
> Now this is how the code should actually be with current django 1.7 in
> order to prevent an error and get the excepted behaviour.
>
> from django.db import IntegrityError, transaction
> @transaction.atomicdef viewfunc(request):
>     create_parent()
>
>     try:
>         with transaction.atomic():
>             generate_relationships()
>     except IntegrityError:
>         handle_exception()
>
>     add_children()
>
>
> It would be great, if the transaction api could work as the first code,
> with the results of the second one. Meaning, even if
> generate_relationships() raises an exception, and it is handled correctly,
> the transaction would still be valid to be used.
>
> Thanks!
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" 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].
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/e347fe6d-78c8-4c15-848d-3a82415c3550%40googlegroups.com
> <https://groups.google.com/d/msgid/django-developers/e347fe6d-78c8-4c15-848d-3a82415c3550%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" 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].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAG_XiSDv0iXGwD%2B%2BLg0uA_9mcf7E6otUh0mgOGkFnORSfVnqAQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to