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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With