The hook is available for automatic retry after a dead end in django and mysql settings

I am using an innoDB table in Django with a mysql database. When examining a mistake

OperationalError: (1213, "A deadlock was detected while trying to block, try restarting the transaction")

I met this answer from Omry . In the last part of the answer he offers

the client should retry automatically.

I am trying to put this logic in code, but at the same time there is some kind of hook available directly in django. Thus, we can establish three-dimensional automation of repetition in the case of a dead end. Also, if someone can give an example of inputting this logic into code (I use django filters).

PS: I could ask this Omry answer below, but I am below 50 points, and also wanted to bring it to django experts.

+3
django mysql mysql-python
source share
1 answer

This is an old question, but since no one has sent an answer, here it is.

To repeat the queries if a deadlock occurred, I made the monkey run the “execute” method of the django CursorWrapper class. This method is called whenever a request is made, so it will work throughout ORM, and you don’t have to worry about deadlocks in your project:

import django.db.backends.utils from django.db import OperationalError import time original = django.db.backends.utils.CursorWrapper.execute def execute_wrapper(*args, **kwargs): attempts = 0 while attempts < 3: try: return original(*args, **kwargs) except OperationalError as e: code = e.args[0] if attempts == 2 or code != 1213: raise e attempts += 1 time.sleep(0.2) django.db.backends.utils.CursorWrapper.execute = execute_wrapper 

What the code does above: it will try to start the request, and if the OperationalError statement is reset with error code 1213 (deadlock), it will wait 200 ms and try again. He will do this 3 times, and if after 3 times the problem is not resolved, the original exception will be raised.

This code should be executed when the django project is loaded into memory, so it’s convenient to place it in the __init__.py file of any of your applications (I put it in the __init__.py file of my main project directory - the one that has the same name as the project django).

Hope this helps anyone in the future.

+5
source share

All Articles