Какой паттерн декоратора рекомендуется использовать для реализации управления транзакциями?
Ответ от нейросети
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, который управляет транзакцией.
Дальше логика такая:
- Вызывается основная функция
create_order. - Если она завершается успешно, вызывается
session.commit(). - Если внутри возникает исключение, выполняется
session.rollback(). - Исключение пробрасывается выше, чтобы его мог обработать вызывающий код.
Такой подход позволяет не писать commit и rollback вручную в каждой бизнес-функции.
Ключевые моменты:
- Декоратор хорошо подходит для сквозной транзакционной логики: commit/rollback вокруг бизнес-операции.
- Основная польза — отделение инфраструктурного кода от бизнес-логики.
- Важно откатывать транзакцию при любом исключении, иначе можно получить неконсистентные данные.
- Если транзакция сложная или вложенная, часто удобнее использовать контекстный менеджер, а не только декоратор.
- Для продакшена обычно учитывают ещё управление сессией, повторные попытки и особенности ORM/БД.
- Декоратор должен быть прозрачным для вызывающего кода и не менять смысл возвращаемого результата.