Sobes.tech
Назад к вопросам
Junior — Middle
72

Какой паттерн декоратора рекомендуется использовать для реализации управления транзакциями?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Для управления транзакциями обычно используют декоратор, который оборачивает бизнес-логику и автоматически делает commit при успехе и rollback при исключении. Такой подход позволяет вынести транзакционную обвязку из основной функции и не дублировать её в каждом месте. В Python это удобно реализуется через обычный декоратор или, если нужен более гибкий контроль, через контекстный менеджер.

Определение:

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

Пример использования:

from functools import wraps

def transactional(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        session = kwargs.get("session")
        if session is None:
            raise ValueError("session is required")

        try:
            result = func(*args, **kwargs)
            session.commit()
            return result
        except Exception:
            session.rollback()
            raise

    return wrapper


@transactional
def create_order(data, session=None):
    order = Order(**data)
    session.add(order)
    return order

Пояснение кода:

Код показывает типичный декоратор для транзакций.
Сначала transactional принимает функцию func и возвращает wrapper.
Внутри wrapper берётся объект session, который управляет транзакцией.

Дальше логика такая:

  1. Вызывается основная функция create_order.
  2. Если она завершается успешно, вызывается session.commit().
  3. Если внутри возникает исключение, выполняется session.rollback().
  4. Исключение пробрасывается выше, чтобы его мог обработать вызывающий код.

Такой подход позволяет не писать commit и rollback вручную в каждой бизнес-функции.

Ключевые моменты:

  • Декоратор хорошо подходит для сквозной транзакционной логики: commit/rollback вокруг бизнес-операции.
  • Основная польза — отделение инфраструктурного кода от бизнес-логики.
  • Важно откатывать транзакцию при любом исключении, иначе можно получить неконсистентные данные.
  • Если транзакция сложная или вложенная, часто удобнее использовать контекстный менеджер, а не только декоратор.
  • Для продакшена обычно учитывают ещё управление сессией, повторные попытки и особенности ORM/БД.
  • Декоратор должен быть прозрачным для вызывающего кода и не менять смысл возвращаемого результата.