Что такое ошибка Transaction rollback?

Ошибка Transaction rollback возникает, когда база данных откатывает транзакцию из-за ошибок или конфликтов.

Причины возникновения

  • Нарушение ограничений целостности
  • Deadlock между транзакциями
  • Превышение таймаута транзакции
  • Ошибки в SQL запросах
  • Нехватка ресурсов БД

Как отладить ошибку

  1. Проверь логи ошибок - найди конкретную причину отката
  2. Проверь ограничения - убедись в соблюдении целостности
  3. Проверь deadlock - найди конфликтующие транзакции
  4. Проверь ресурсы - убедись в достаточности ресурсов

Как исправить ошибку

1. Обработай deadlock

 1# Проверь deadlock
 2SHOW ENGINE INNODB STATUS;
 3
 4# Настрой таймауты
 5SET innodb_lock_wait_timeout = 50;
 6
 7# Используй правильный порядок блокировок
 8START TRANSACTION;
 9SELECT * FROM table1 WHERE id = 1 FOR UPDATE;
10SELECT * FROM table2 WHERE id = 1 FOR UPDATE;
11-- выполняй операции
12COMMIT;

2. Исправь ограничения целостности

 1# Проверь данные перед вставкой
 2START TRANSACTION;
 3
 4-- Проверь ограничения
 5SELECT COUNT(*) FROM parent_table WHERE id = 123;
 6
 7-- Вставь только если родитель существует
 8IF (SELECT COUNT(*) FROM parent_table WHERE id = 123) > 0 THEN
 9    INSERT INTO child_table (parent_id, data) VALUES (123, 'value');
10END IF;
11
12COMMIT;

3. Настрой таймауты

1# Настрой таймауты транзакций
2SET SESSION innodb_lock_wait_timeout = 50;
3SET SESSION lock_wait_timeout = 50;
4
5# Или в конфигурации
6[mysqld]
7innodb_lock_wait_timeout = 50
8lock_wait_timeout = 50

4. Используй retry логику

 1# Python с retry
 2import time
 3from sqlalchemy.exc import OperationalError
 4
 5def execute_with_retry(session, operation, max_retries=3):
 6    for attempt in range(max_retries):
 7        try:
 8            result = operation(session)
 9            session.commit()
10            return result
11        except OperationalError as e:
12            if "Deadlock" in str(e) and attempt < max_retries - 1:
13                session.rollback()
14                time.sleep(0.1 * (attempt + 1))
15                continue
16            raise

Как мониторить подобные ошибки

  • Мониторь количество rollback
  • Логируй deadlock события
  • Настрой алерты на частые откаты
  • Используй мониторинг производительности

FAQ

В: Как предотвратить deadlock?

О: Используй одинаковый порядок блокировок во всех транзакциях.

В: Что делать с частыми откатами?

О: Оптимизируй запросы, уменьши размер транзакций, настрой таймауты.

В: Можно ли отменить rollback?

О: Нет, rollback необратим. Используй retry логику для повторного выполнения.

Лучшие практики

  • Держи транзакции короткими
  • Используй правильный порядок блокировок
  • Настрой адекватные таймауты
  • Используй retry логику
  • Мониторь производительность транзакций