Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TransactionManagementError - This is forbidden when an 'atomic' block is active

While upgrading my project from django 1.5.1 to 1.6.5, I am facing this weird issue.

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

I am aware of the Database Transaction changes for django 1.6 and made the setting changes accordingly. Works for most part, except when request.user object is accessed.

The code, for instance:

with transaction.atomic():
    if hasattr(request, 'user') and getattr(request.user, 'id', None):
        #blah

Here is the stacktrace:

Environment:


Request Method: GET
Request URL: <domain>/api/v1/browser_id/

Django Version: 1.6.5
Python Version: 2.7.3

<Installed Applications & Middlewares snipped for brevity>

Traceback:
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  112.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/db/transaction.py" in inner
  371.                 return func(*args, **kwargs)
File "/home/kravindra/workspace/puppysite/puppy/kennel/views/etag_session.py" in browser_id
  43.         if hasattr(request, 'user') and getattr(request.user, 'id', None):
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/utils/functional.py" in inner
  213.             self._setup()
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/utils/functional.py" in _setup
  298.         self._wrapped = self._setupfunc()
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/contrib/auth/middleware.py" in <lambda>
  18.         request.user = SimpleLazyObject(lambda: get_user(request))
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/contrib/auth/middleware.py" in get_user
  10.         request._cached_user = auth.get_user(request)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/contrib/auth/__init__.py" in get_user
  140.         user_id = request.session[SESSION_KEY]
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/contrib/sessions/backends/base.py" in __getitem__
  47.         return self._session[key]
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/contrib/sessions/backends/base.py" in _get_session
  173.                 self._session_cache = self.load()
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/contrib/sessions/backends/cached_db.py" in load
  52.                 self.create()
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/contrib/sessions/backends/db.py" in create
  40.                 self.save(must_create=True)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/contrib/sessions/backends/cached_db.py" in save
  62.         super(SessionStore, self).save(must_create)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/contrib/sessions/backends/db.py" in save
  63.                 obj.save(force_insert=must_create, using=using)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/db/models/base.py" in save
  545.                        force_update=force_update, update_fields=update_fields)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/db/models/base.py" in save_base
  582.                                    update_fields=update_fields, raw=raw, using=using)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py" in send
  185.             response = receiver(signal=self, sender=sender, **named)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/db/transaction.py" in inner
  430.             with self:
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/db/transaction.py" in __enter__
  422.         self.entering(self.using)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/db/transaction.py" in entering
  483.         enter_transaction_management(using=using)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/db/transaction.py" in enter_transaction_management
  70.     get_connection(using).enter_transaction_management(managed, forced)
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/db/backends/__init__.py" in enter_transaction_management
  287.         self.validate_no_atomic_block()
File "/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/db/backends/__init__.py" in validate_no_atomic_block
  367.                 "This is forbidden when an 'atomic' block is active.")

Exception Type: TransactionManagementError at /api/v1/browser_id/
Exception Value: This is forbidden when an 'atomic' block is active.

Looking at the stacktrace,

/usr/local/virtualenvs/karthik-django165/local/lib/python2.7/site-packages/django/contrib/sessions/backends/cached_db.py in load
                self.create() ...
▼ Local vars
Variable    Value
e   
DoesNotExist('Session matching query does not exist.',)
self    
<django.contrib.sessions.backends.cached_db.SessionStore object at 0x7f61d401c6d0>
data    
None

SessionStore raises an exception.

Using POSTGRES as the backend database. The backend session store related settings are:

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' #which is persistent storage

ATOMIC_REQUESTS = True

Any pointers on how to fix this issue?

I found that there are a bunch of Questions on SO, and blogposts that address TransactionManagementError issue in general, but nothing to address this issue in particular

like image 781
karthikr Avatar asked Aug 18 '14 19:08

karthikr


1 Answers

From the traceback it looks like one of your post_save signal receiver is still using one of the following deprecated transaction APIs:

  • transaction.Transaction
  • transaction.autocommit
  • transaction.commit_on_success
  • transaction.commit_manually
  • commit_on_success_unless_managed

Make sure to replace it with a transaction.atomic instance instead and your issue should go away.

Let me know if you have trouble finding the culprit receiver.

like image 177
Simon Charette Avatar answered Oct 06 '22 01:10

Simon Charette