87๐
After getting a similar issue and wasting hours on it I figured out how to debug this situation.
For some reason the @transaction.commit_manually decorator silences exceptions that occur in the function.
Temporarily remove the decorator from your function, youโll now see the exception, fix it and put the decorator back!
9๐
I had the same problem. The only solution I found was to use a try/finally clause to ensure a commit happens after the render.
@transaction.commit_manually
def xyz(request):
committed = False
try:
if ABC:
success = something()
if success:
status = "success"
transaction.commit()
committed = True
else:
status = "dataerrors"
transaction.rollback()
committed = True
else:
status = "uploadproblem"
transaction.rollback()
committed = True
return render(request, "template.html", {
'status': status,
})
finally:
if not committed:
transaction.rollback() # or .commit() depending on your error-handling logic
Makes no sense, but it worked for me.
- [Django]-Django ORM, group by day
- [Django]-Why is factory_boy superior to using the ORM directly in tests?
- [Django]-Django โ Website Home Page
2๐
I had the same issue and learned that even if you properly close the transaction manually in case of exceptions, if you then write to the orm again within the manual-transaction scope, it seems to reopen the transaction somehow and causes the transaction exception.
with transaction.commit_manually():
try:
<exciting stuff>
transaction.commit()
except Exception, e:
transaction.rollback()
o.error='failed' <== caused transaction exception
- [Django]-Django: how can I tell if the post_save signal triggers on a new object?
- [Django]-Count frequency of values in pandas DataFrame column
- [Django]-Django MySQL error when creating tables
2๐
another reason why you might be seeing this issue is when you have multiple dbโs in the system.
I was able to overcome this error with
@transaction.commit_manually(using='my_other_db')
def foo():
try:
<db query>
transaction.commit(using='my_other_db')
except:
transaction.rollback(using='my_other_db')
- [Django]-Function decorators with parameters on a class based view in Django
- [Django]-Sublime Text 2 & 3 setup for python / django with code completion
- [Django]-How to convert JSON data into a Python object?
1๐
This always happens when an unhandled exception occurs somewhere in the code. In my case, for some reason, the exception was not thrown to the debugger which is what caused the confusion for me.
- [Django]-Return the current user with Django Rest Framework
- [Django]-Django south migration โ Adding FULLTEXT indexes
- [Django]-How to set a value of a variable inside a template code?
1๐
I had similar problem, maybe this code works fine for you:
@transaction.commit_on_success
def xyz(request):
if ABC:
success = something()
if success:
status = "success"
else:
status = "dataerrors"
transaction.rollback()
else:
status = "uploadproblem"
transaction.rollback()
return render(request, "template.html", {
'status': status,
})
- [Django]-How do I iterate over the options of a SelectField in a template?
- [Django]-How to pass an array in Django to a template and use it with JavaScript
- [Django]โbash: ./manage.py: Permission denied
1๐
As other people have said, exceptions occurring within the decorated function are โlostโ because they are overwritten by the TransactionManagementError
exception.
I propose to extend the transaction.commit_manually
decorator. My decorator transaction_commit_manually
uses the transaction.commit_manually
decorator internally; if an exception occurs in the decorated function, my decorator catches the exception, performs a transaction.rollback()
and raises the exception again. Thus the transaction is cleared correctly, and the original exception is not lost.
def _create_decorator_transaction_commit_manually(using=None):
def deco(f):
def g(*args, **kwargs):
try:
out = f(*args, **kwargs)
except Exception as e:
if using is not None:
transaction.rollback(using=using)
else:
transaction.rollback()
raise e
return out
if using is not None:
return transaction.commit_manually(using=using)(g)
return transaction.commit_manually(g)
return deco
def transaction_commit_manually(*args, **kwargs):
"""
Improved transaction.commit_manually that does not hide exceptions.
If an exception occurs, rollback work and raise exception again
"""
# If 'using' keyword is provided, return a decorator
if 'using' in kwargs:
return _create_decorator_transaction_commit_manually(using=kwargs['using'])
# If 'using' keyword is not provided, act as a decorator:
# first argument is function to be decorated; return modified function
f = args[0]
deco = _create_decorator_transaction_commit_manually()
return deco(f)
- [Django]-Object has no attribute 'get'
- [Django]-Django IntegerField with Choice Options (how to create 0-10 integer options)
- [Django]-Add an object by id in a ManyToMany relation in Django
0๐
I was having the same problem and tried various approaches. Here is what worked for me but i am not sure if this is the right way to do it. Change your return statement to:
with transaction.commit_on_success():
return render(request, "template.html", {
'status': status,
})
Django Pros, is this the right approach?
- [Django]-Get date from a Django DateTimeField
- [Django]-Specifying a mySQL ENUM in a Django model
- [Django]-Custom QuerySet and Manager without breaking DRY?
0๐
Put your code in try /except block .In except block just do a transaction.rollback and log the exception object.
@transaction.commit_manually
def xyz(xyz):
try:
some_logic
transaction.commit()
except Exception,e:
transaction.rollback()
print str(e)
- [Django]-Best place to clear cache when restarting django server
- [Django]-'RelatedManager' object has no attribute
- [Django]-AbstractUser vs AbstractBaseUser in Django?
0๐
Take backup of database if needed and remove table ROLLBACK_TEST
from your database.
mysql> DROP TABLE `ROLLBACK_TEST`;
- [Django]-What's the purpose of Django setting โSECRET_KEYโ?
- [Django]-Setting default value for Foreign Key attribute in Django
- [Django]-CharField with fixed length, how?