Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

This is forbidden when an 'atomic' block is active. Django 1.8

I am receiving the error This is forbidden when an 'atomic' block is active. on a Django 1.8 install.

I've tried wrapping it in both with transaction.atomic(): as well as creating an exception for IntegrityError

Here's my code:

item = Item.objects.filter(item_id = data['item_id'])[:1][0]
iserializer = ItemSerializer(item, data=data, partial=True)
try:
    with transaction.atomic():
        if iserializer and iserializer.is_valid():
            iserializer.save()
except IntegrityError:
    pass

What could be causing it? Why is my exception handling not working to keep this error from being received?

Here's the traceback:

Traceback (most recent call last):
  File "<console>", line 4, in <module>
  File "/home/vagrant/client/venv/bin/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 186, in save
    self.instance = self.update(self.instance, validated_data)
  File "/home/vagrant/client/venv/bin/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 880, in update
    instance.save()
  File "/vagrant/client/client/items/models.py", line 45, in save
    transaction.commit()
  File "/home/vagrant/client/venv/bin/local/lib/python2.7/site-packages/django/db/transaction.py", line 42, in commit
    get_connection(using).commit()
  File "/home/vagrant/client/venv/bin/local/lib/python2.7/site-packages/django/db/backends/base/base.py", line 172, in commit
    self.validate_no_atomic_block()
  File "/home/vagrant/client/venv/bin/local/lib/python2.7/site-packages/django/db/backends/base/base.py", line 322, in validate_no_atomic_block
    "This is forbidden when an 'atomic' block is active.")
TransactionManagementError: This is forbidden when an 'atomic' block is active.
like image 575
Steven Matthews Avatar asked Nov 17 '15 15:11

Steven Matthews


People also ask

What does transaction atomic do in Django?

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. If there is an exception, the changes are rolled back.

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

Based on the traceback, it looks like you're overriding the model's save() method and explicitly calling transaction.commit().

File "/vagrant/client/client/items/models.py", line 45, in save
  transaction.commit()

As the error indicates, you can't do that inside an atomic block since the block is expecting to do that itself.

More fundamentally, the error here is in mixing the high-level transactions API (transaction.atomic()) and the low-level transactions API (transaction.commit()). They are meant to be alternatives to each other, not used together.

From the documentation:

Always prefer atomic() if possible at all. It accounts for the idiosyncrasies of each database and prevents invalid operations. The low level APIs are only useful if you’re implementing your own transaction management.

like image 75
Kevin Christopher Henry Avatar answered Sep 18 '22 17:09

Kevin Christopher Henry