解决django.db.utils.OperationalError: (1213, 'Deadlock found when trying to get lock; try restarting transaction') 死锁问题
原因:因为设置了SESSION_SAVE_EVERY_REQUEST=Ture
,导致每个接口没有修改的状态下也更改session的过期时间。
-
查看代码发现SessionMiddleware源码,遇到UpdateError异常直接抛出。
try: request.session.save() except UpdateError: raise SuspiciousOperation( "The request's session was deleted before the " "request completed. The user may have logged " "out in a concurrent request, for example." )
-
创建一个新的中间件类,继承自SessionMiddleware
import time from django.db import transaction from django.contrib.sessions.backends.base import UpdateError from django.contrib.sessions.middleware import SessionMiddleware class CustomSessionMiddleware(SessionMiddleware): # 继承SessionMiddleware 遇到异常重试3次 def process_response(self, request, response): try: return super().process_response(request, response) except Exception as e: print('errors: {}'.format(e)) max_retries = 3 retries = 0 success = False while retries < max_retries and not success: try: with transaction.atomic(): request.session.save() success = True except UpdateError: print('试图获得锁时发现死锁;尝试重新启动事务!') retries += 1 time.sleep(1) if not success: # 处理超过最大重试次数的情况 if request.method == "POST": print(request.body, '================>') else: print(request.GET, '================>') print('OperationalError 异常已经重试最大次数') return response
-
在Django的配置文件(settings.py)中将默认的SessionMiddleware替换为自定义的中间件。
MIDDLEWARE = [ # 'django.contrib.sessions.middleware.SessionMiddleware', # 重写SessionMiddleware 'middleware.session.CustomSessionMiddleware', ]
从小白到大神的蜕变~~