@NubasLol

Как в коде в стиле «clean architecture» использовать транзакции?

Пример репозитория

https://github.com/bxcodec/go-clean-arch

Смотрел примеры, как выше, читал статьи но так для себя и не понял. Что делать с транзакицями. Ведь методы репозитория не принимают ничего кроме данных. По итогу решительно не ясно.

Например у меня есть OrderUseCase {orderRepository, paymentRepository}

И метод newOrder()

Как правильно в нем написать, что бы создание заказа, и списание средств со счета пользователя было в транзакции. Или это все нужно пихать в 1 репозиторий, но потом будет дублирование кода ведь?
  • Вопрос задан
  • 363 просмотра
Пригласить эксперта
Ответы на вопрос 2
@deliro
Нужно понимать, что orderRepository и paymentRepository — это абстракции, а фактически данные могут храниться как в одной базе, так и в совершенно разных. Например, orderRepository находится на сервере S1 в базе Redis, а paymentRepository — на серверах S2, S3, S4 в базе PostgreSQL. Поэтому, классические транзакции здесь неприменимы. Этим можно пренебречь в большинстве случаев и не переусложнять систему, а можно пойти "правильным" путём и использовать распределённые транзакции, например, саги https://microservices.io/patterns/data/saga.html
Ответ написан
@Akela_wolf
Extreme Programmer
Тут все довольно просто. У нас есть слой бизнес-логики, который имеет 3 интерфейса:
TransactionManager - собственно менеджер транзакций
OrderRepository - репозиторий заказов
PaymentRepository - репозиторий платежей

И, допустим, нам нужно транзакционно сделать следующий сценарий: "при получении платежа записать его в БД и изменить статус заказа на PAID" (пишу пример на Kotlin, надеюсь понятно)
transactionManager.inTransaction {
  order.status = PAID
  paymentRepository.save(payment)
  orderRepository.save(order)
}

Собственно дальше - это уже вопрос реализации TransactionManager. Если мы имеем дело с простым случаем, таким как хранение данных в SQL Database, то его реализация должна быть понятна. Если более сложный случай - то распределенные транзакции, либо пустая реализация (транзакционность не поддерживается). Разумеется, при инжекции зависимостей в модуль бизнес-логики реализация менеджера транзакций должна соответствовать реализации репозиториев (мало толку будет если менеджер транзакций реализует транзакционность в БД, а репозитории - хранение в файлах). Но это уже слегка другой разговор, тут на помощь приходят фабрики и подобные шаблоны.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы