这是一个老问题,但由于没有人发布答案,所以就在这里。
为了在发生死锁时重试查询,我所做的是我猴子修补了 django 的 CursorWrapper 类的“执行”方法。每当进行查询时都会调用此方法,因此它将在整个 ORM 中工作,您不必担心项目中的死锁:
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
上面的代码所做的是:它将尝试运行查询,如果抛出带有错误代码 1213(死锁)的 OperationalError,它将等待 200 毫秒并重试。它将执行 3 次,如果 3 次后问题仍未解决,则会引发原始异常。
此代码应在 django 项目加载到内存时执行,因此将其放在__init__.py
任何应用程序的文件中的好地方(我放在__init__.py
项目主目录的文件中 - 具有相同名称的文件)作为你的 Django 项目)。
希望这对将来的任何人都有帮助。