Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Transaction managed block ended with pending COMMIT/ROLLBACK

I have a view function which needs to be manually transaction managed, but when I apply the @transaction.commit_manually decorator, django ALWAYS raises the below exception.

As you can see from the code trace below, the transaction is committed right before return from the view.

I am using sqlite, both on windows and linux, with django 1.4.

The following is the output of django_trace, followed by the exception. To be clear: this happens whether or not I use django_trace, and when there are no decorators, no exception whatsoever is raised. This is not being caused by a "swallowed" exception.

Note that line 60 in the below is inside a context processor, and hence outside of the commit_manually-wrapped view.

01->mainapp.views:1321:         transaction.commit()
01->mainapp.views:1322:         return render_to_response('mainapp/templates/incorporate.html',
01->mainapp.views:1323:                                       RequestContext(request, form_params))
02-->mainapp.views:60:     transaction.rollback_unless_managed()
02-->mainapp.views:61:     return {'home_login_form': AuthenticationForm(request)}
Traceback (most recent call last):
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\contrib\staticfiles\handlers.py", line 67, in __call__
    return self.application(environ, start_response)
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\contrib\staticfiles\handlers.py", line 67, in __call__
    return self.application(environ, start_response)
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\core\handlers\wsgi.py", line 241, in __call__
    response = self.get_response(request)
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\core\handlers\base.py", line 179, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\core\handlers\base.py", line 221, in handle_uncaught_exception
    return debug.technical_500_response(request, *exc_info)
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\core\handlers\base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Marcin\Documents\oneclickcos\oneclickcos\mainapp\decorators.py", line 26, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\db\transaction.py", line 209, in inner
    return func(*args, **kwargs)
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\db\transaction.py", line 203, in __exit__
    self.exiting(exc_value, self.using)
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\db\transaction.py", line 288, in exiting
    leave_transaction_management(using=using)
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\db\transaction.py", line 52, in leave_transaction_management
    connection.leave_transaction_management()
  File "C:\Users\Marcin\Documents\oneclickcos\lib\site-packages\django\db\backends\__init__.py", line 119, in leave_transaction_management
    raise TransactionManagementError("Transaction managed block ended with "
TransactionManagementError: Transaction managed block ended with pending COMMIT/ROLLBACK

To be clear, I have checked the other questions on this topic, and they DO NOT have the solution to my problem.

like image 565
Marcin Avatar asked Dec 01 '22 23:12

Marcin


1 Answers

It turns out that during template rendering, there was database access, so the usual pattern like:

return render_to_response('mainapp/templates/incorporate.html',
                          RequestContext(request, form_params))

was the cause of the problem. I needed to replace that with:

retval = render_to_response('mainapp/templates/incorporate.html',
                                      RequestContext(request, form_params))
transaction.commit()
return retval

In addition, other SO answers reveal that the transaction management decorators hide all exceptions and instead raise the transaction management exception. Unfortunately, the easiest way to diagnose this is to run without the decorator, and see if an exception is occurring, or wrap your whole view in a try/except.

like image 164
Marcin Avatar answered Dec 24 '22 00:12

Marcin