Повторите попытку в тупике для MySQL / SQLAlchemy

Я искал довольно долгое время и не могу найти решение моей проблемы. Мы используем 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 

2 Solutions collect form web for “Повторите попытку в тупике для MySQL / SQLAlchemy”

Вы не можете сделать это с помощью Session извне. Session должна была бы поддерживать это внутренне. Это будет связано с сохранением большого количества частного государства, поэтому это может не стоить вашего времени.

Я полностью отбросил большинство материалов ORM в пользу интерфейса SQLAlchemy Core более низкого уровня. Используя этот (или даже любой интерфейс dbapi), вы можете тривиально использовать декоратор retry_on_deadlock_decorator (см. Вопрос выше), чтобы создать обертку db.execute поддерживающую повторную db.execute .

  @retry_on_deadlock_decorator def deadlock_safe_execute(db, stmt, *args, **kw): return db.execute(stmt, *args, **kw) 

И вместо

  db.execute("UPDATE users SET active=0") 

вы делаете

  deadlock_safe_execute(db, "UPDATE users SET active=0") 

который автоматически повторит попытку, если произойдет взаимоблокировка.

Вы использовали такой код?

 try: Perform table transaction break except: rollback delay try again to perform table transaction 

Единственный способ по-настоящему справиться с блокировками – написать свой код, чтобы ожидать их. Это, как правило, не очень сложно, если ваш код базы данных хорошо написан. Часто вы можете просто попробовать попробовать / поймать логику выполнения запроса и искать тупик при возникновении ошибок. Если вы его поймаете, нормальная вещь – просто попытаться снова выполнить неудавшийся запрос.

Полезные ссылки:

  • Как справиться с тупиковыми замками
  • Понимание Autocommit
  • Свойство MySQLConnection.autocommit
  • Наследование SQLAlchemy
  • атрибут класса backref
  • AttributeError: объект 'list' не имеет атрибута '_sa_instance_state'
  • Удаление объекта из сеанса SQLAlchemy до его сохранения
  • Как выполнить «левое внешнее соединение» в SqlAlchemy
  • Сохранять порядок списка в разбивке по страницам в sql
  • Получить количество строк в таблице с помощью SQLAlchemy
  • SQLAlchemy и django, готово ли это производство?
  •  
    Interesting Posts for Van-Lav

    Настройка обработки исключений по умолчанию Python

    Как преобразовать синтаксис уценки WMD в HTML на моем сайте?

    Python Metaclass: Понимание 'with_metaclass ()'

    Программно проверить, установлен ли PHP с помощью Python

    Сравнение поплавков в столбце pandas

    Как я могу получить доступ к XML-элементам с именами, используя BeautifulSoup?

    Python ValueError: небезопасный струйный рассол

    Каков наиболее эффективный способ найти факторы в списке?

    Как я могу украсить все функции класса, не набирая его снова и снова для каждого добавленного метода? Python

    Является ли python ctypes.c_long 64 бит на 64-битных системах?

    Лучший способ масштабирования матричных переменных в схеме линейного программирования SCIPY

    Изображение.show () не отображает изображение

    Сравните, если две переменные ссылаются на один и тот же объект в python

    Как выполнять функцию асинхронно каждые 60 секунд в Python?

    Python Regex – Предложение не включает строки

    Python - лучший язык программирования в мире.