guettli
guettli

Reputation: 27107

Django: atomic(): Force transaction, raise AssertionError if already inside a transaction

I have a problem with atomic() in Django:

https://docs.djangoproject.com/en/1.7/topics/db/transactions/#django.db.transaction.atomic

For some methods (called outside request/response cycle) I need to be sure, that the method is executed in one transaction. I must force durability. atomic() would silently use a savepoints if already inside a transaction.

Remember: ACID http://en.wikipedia.org/wiki/ACID

The keyword argument savepoint for atomic() does not help here. If you use savepoint=False atomic() does silently nothing (according to the docs) if already inside a transaction.

I need an Exception if the is already a transaction running.

Unfortunately the old is_managed() is deprecated without a replacement.

How can I create a atomic_raise_exception_if_already_in_transaction() decorator?

Upvotes: 4

Views: 1133

Answers (2)

catavaran
catavaran

Reputation: 45595

If you use only the atomic() then you can check for in_atomic_block property of the connection:

>>> from django.db import transaction
>>> transaction.get_connection().in_atomic_block
False
>>> with transaction.atomic():
...     print transaction.get_connection().in_atomic_block
... 
True
>>> transaction.get_connection().in_atomic_block
False
>>> 

Upvotes: 4

Maciej Gol
Maciej Gol

Reputation: 15864

Detecting whether there is a transaction running on your DB connection depends on the behaviour of your db backend library. E.g. psycopg2 for postgresql does implicitly start a new transaction when submitting a new query when previous transaction has been finished unless explicit autocommit mode has been turned on. In the former case, all queries will run inside a transaction thus leaving you with no reliable checks other than commiting current transaction.

You can, on the other hand, detect whether there is an atomic block active, see docs. You can use the connection.in_atomic_block property to check whether there has been any atomic block activated.

Upvotes: 1

Related Questions