Чистая архитектура - как обращаться с транзакциями в базе данных?

В «чистой архитектуре» интеракторы (варианты использования) отвечают за определение бизнес-логики. Большинство примеров определяют варианты использования следующим образом:

public MyUseCase() {

  public boolean execute(...) {
    int id = repository.insert(a)
    if(id > 0) {
      b.aId= id;
      repository.insert(b);
      ...
    }
  }
}

Интеракторы используют в основном простые CRUD-операции или запросы к репозиторию. Приведенный выше пример является синхронным для простоты, но вы можете найти репозитории с тем же подходом, используя асинхронные решения, такие как обратные вызовы или rxjava.

Но как насчет некомпетентности варианта использования. Например, вы не можете быть на 100% уверены, что после вставки a он все еще будет там, когда вы вставите b. Что делать, если после вставки a вы получите исключение RepositoryException при вставке b.

Все репозитории, которые я видел до сих пор, не учитывают это, поэтому мой вопрос:

Какое решение вышеупомянутой проблемы в чистой архитектуре?


person Marcin    schedule 01.08.2017    source источник


Ответы (1)


Этот ответ может быть запоздалым, но я боролся с той же проблемой и пришел к выводу, что управление транзакциями, по сути, является частью варианта использования, например: «Если что-то пойдет не так с B, верните состояние A». Таким образом, это можно и нужно явно указать в вашем UseCase, возможно, с помощью какого-то «DataManagerRepo», например:

public MyUseCase() {

    public boolean execute(...) {
        dataManagerRepository.openTransaction()
        try {
            int id = repository.insert(a)
            if(id > 0) {
            b.aId= id;
            repository.insert(b);
            ...
        }
        catch (MyException exc) {
            dataManagerRepository.rollbackTransaction()
        }

        dataManagerRepository.commitTransaction()
    }
}

Имена могут отличаться, чтобы абстрагироваться от механизма целостности, но идея та же. Надеюсь, это кому-нибудь поможет.

person Mike Doudkin    schedule 07.09.2017
comment
Как это решение будет работать, если вариант использования включает два или более вариантов использования? Как это решение будет работать, если один вариант использования должен работать в двух или более репозиториях? - person elad.chen; 26.08.2019
comment
Можете ли вы добавить код своего dataManagerRepository? - person Sean Stayns; 22.09.2020
comment
@SeanStayns, этого не существует, я все это придумал - person Mike Doudkin; 26.02.2021