How Django atomic requests works?

David D. picture David D. · Dec 7, 2014 · Viewed 8.2k times · Source

I'd like my Django views to be atomic. I mean, if there is 2 DB-writes in the view, I want either 0 write, either 2 writes.

For example:

def test_view(request):
    ''' A test view from views.py '''

    MyClass.objects.create()
    raise Exception("whatever")
    MyClass.objects.create()

What I found in documentation seemed promising :

A common way to handle transactions on the web is to wrap each request in a transaction. Set ATOMIC_REQUESTS to True in the configuration of each database for which you want to enable this behavior.

It works like this. Before calling a view function, Django starts a transaction. If the response is produced without problems, Django commits the transaction. If the view produces an exception, Django rolls back the transaction.

However, even if I set ATOMIC_REQUESTS = True, when calling test_view(), the first MyClass object is created! What am I missing?

Note : I'm using Django 1.7

Answer

Daniel Roseman picture Daniel Roseman · Dec 7, 2014

ATOMIC_REQUESTS is an an attribute of the database connection settings dict, not the top-level settings. So, for example:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': '127.0.0.1',
        'PORT': '5432',
        'ATOMIC_REQUESTS': True,
    }
}