Hook available for automatic retry after deadlock in django and mysql setup

前端 未结 1 1094
长情又很酷
长情又很酷 2021-01-18 16:16

I am using innoDB table in Django with mysql database. During investigation of error

OperationalError: (1213, \'Deadlock found when trying to get loc

相关标签:
1条回答
  • 2021-01-18 16:29

    This is an old question but since nobody posted an answer, here it is.

    In order to retry queries if a deadlock happens, what I did was I monkey patched the method "execute" of django's CursorWrapper class. This method is called whenever a query is made, so it will work across the entire ORM and you won't have to worry about deadlocks across 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 above does is: it will try running the query and if an OperationalError is thrown with the error code 1213 (a deadlock), it will wait for 200 ms and try again. It will do this 3 times and if after 3 times the problem was not solved, the original exception is raised.

    This code should be executed when the django project is being loaded into memory and so a good place to put it is in the __init__.py file of any of your apps (I placed in the __init__.py file of my project's main directory - the one that has the same name as your django project).

    Hope this helps anyone in the future.

    0 讨论(0)
提交回复
热议问题