Я искал довольно долгое время и не могу найти решение своей проблемы. Мы используем SQLAlchemy в сочетании с MySQL для нашего проекта и несколько раз сталкиваемся с ужасной ошибкой:
1213, 'Обнаружена тупиковая ситуация при попытке получить блокировку; попробуйте перезапустить транзакцию».
В этом случае мы хотели бы попытаться перезапустить транзакцию не более трех раз.
Я начал писать декоратор, который делает это, но я не знаю, как сохранить состояние сеанса до сбоя и повторить ту же транзакцию после него? (Поскольку 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