Повторите попытку в тупике для 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
  • Динамическое установление соединения базы данных Flask-SQLAlchemy в приложении с несколькими арендаторами
  • SQLALchemy DB Session with Flask, Postgres
  • SqlAlchemy: самореализованное значение по умолчанию в качестве запроса
  • Как отправить результаты запроса в поле WTForm?
  • Удаление объекта из сеанса SQLAlchemy до его сохранения
  • Подсчет отношений в SQLAlchemy
  • SQLAlchemy, Flask: получить отношения из db.Model
  • Как я могу профилировать приложение с поддержкой SQLAlchemy?
  • Как сопоставить один класс с несколькими таблицами с SQLAlchemy?
  • SQLAlchemy - самореляционное отношение Many-to-many с дополнительным столбцом
  • Принуждение sqlalchemy ORM get () вне карты идентификации
  •  
    Interesting Posts for Van-Lav

    Перекрытие обнаружения сообщества с помощью играфа или других библиотек

    Установка lxml в virtualenv через ошибку установки пакета: команда 'x86_64-linux-gnu-gcc' не выполнена

    Как проверить, находится ли конкретное целое число в списке

    Как эффективно хранить этот проанализированный XML-документ в базе данных MySQL с помощью Python?

    KeyError: «данные» с клиентом API Python

    Python: Рекомендуемый способ перемещения сложных структур словаря, импортированных из JSON?

    Использование numpy для эффективного преобразования 16-битных данных изображения в 8 бит для отображения с масштабированием интенсивности

    Нет модуля с именем Image tk

    Как вернуть указатель на структуру в ctypes?

    Spark добавляет новый столбец в dataframe со значением из предыдущей строки

    маршал сбрасывается быстрее, cPickle быстрее загружается

    Позиционный аргумент против ключевого слова

    Значение параметра тензорного потока Tensorflow variable_scope означает значение параметра

    Как получить токен доступа пользователя в Python

    В Python, как я могу получить глобальные переменные, которые используются в функции?

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