#33882: async transaction.atomic
-------------------------------+--------------------------------------
     Reporter:  alex           |                    Owner:  nobody
         Type:  New feature    |                   Status:  new
    Component:  Uncategorized  |                  Version:  4.0
     Severity:  Normal         |               Resolution:
     Keywords:                 |             Triage Stage:  Unreviewed
    Has patch:  0              |      Needs documentation:  0
  Needs tests:  0              |  Patch needs improvement:  0
Easy pickings:  0              |                    UI/UX:  0
-------------------------------+--------------------------------------

Comment (by alex):

 django supports db transactions with rollback via the
 django.db.transaction.atomic function which can either be used as
 decorator or as contextmanager.
 Everything wrapped within is executed as transaction, see:

 https://docs.djangoproject.com/en/4.0/topics/db/transactions/

 That is very nice but now there is a ''little'' problem:
 it isn't async safe:

 https://forum.djangoproject.com/t/is-it-possible-to-use-transaction-
 atomic-with-async-functions/8924

 When looking through the contextmanager (which is actually a class named
 Atomic in the same file) I saw that __enter__ and __exit__ use simple db
 operations.
 If we use the wrappers like suggested (`__aenter__` and `__aexit__`) then
 everything should be fine in theory. In praxis I need to test the code (I
 have not much time so it may be easier if somebody else tries this out)

 I build a wrapper class like this (of course it would be better to have it
 in Atomic itself so the atomic function can be used and no manual
 initialization is required):
 {{{
 #!python
 from asgiref.sync import sync_to_async
 from django.db.transaction import Atomic

 class AsyncAtomic(Atomic):
     __aenter__ = sync_to_async(Atomic.__enter__, thread_sensitive=True)
     __aexit__ = sync_to_async(Atomic.__exit__, thread_sensitive=True)
 }}}
 '''Warning''': untested

 I must confess: the use case is very rare and is only useful in
 combination with select_for_update for delaying row updates (otherwise it
 is an antipattern as it causes slow transactions). And this is why I
 haven't a good example code.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33882#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 view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701825d6c8426-72b4f013-9192-44e6-bb61-7679b47635d1-000000%40eu-central-1.amazonses.com.

Reply via email to