我已经搜索了相当长一段时间,但找不到解决我的问题的方法。我们在项目中使用SQLAlchemy与MySQL,并多次遇到可怕的错误:
1213, 'Deadlock found when trying to get lock; try restarting transaction'。
在这种情况下,我们想尝试最多三次重新启动事务。
我已经开始编写一个装饰器来实现此功能,但我不知道如何在失败之前保存会话状态并重试同一事务?(因为SQLAlchemy要求在引发异常时回滚)
到目前为止,我的工作如下:
def retry_on_deadlock_decorator(func):
lock_messages_error = ['Deadlock found', 'Lock wait timeout exceeded']
@wraps(func)
def wrapper(*args, **kwargs):
attempt_count = 0
while attempt_count < settings.MAXIMUM_RETRY_ON_DEADLOCK:
try:
return func(*args, **kwargs)
except OperationalError as e:
if any(msg in e.message for msg in lock_messages_error) \
and attempt_count <= settings.MAXIMUM_RETRY_ON_DEADLOCK:
logger.error('Deadlock detected. Trying sql transaction once more. Attempts count: %s'
% (attempt_count + 1))
else:
raise
attempt_count += 1
return wrapper