Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Django atomic requests works?

Tags:

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

like image 322
David D. Avatar asked Dec 07 '14 18:12

David D.


People also ask

How does Django atomic transaction work?

Django provides a single API to control database transactions. Atomicity is the defining property of database transactions. atomic allows us to create a block of code within which the atomicity on the database is guaranteed. If the block of code is successfully completed, the changes are committed to the database.

How does Django handle concurrency?

In terms of Django, optimistic concurrency control can be implemented by overriding the save method on your model class... And, of course, for either of these concurrency mechanisms to be robust, you have to consider transactional control.

Can't execute queries until the end of the atomic block?

You can't execute queries until the end of the 'atomic' block." is raised when you try to used a database connection after a database exception even those autocommit was set to false from the start. It should be up to the user how to handle the database exception and the transaction as autocommit was set to false.


1 Answers

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,
    }
}
like image 181
Daniel Roseman Avatar answered Sep 21 '22 11:09

Daniel Roseman