generi c транзакция / обработка ошибок с помощью rx java (mongodb) - PullRequest
0 голосов
/ 09 июля 2020

реактивный драйвер mongodb java поставляется с этими методами для обработки транзакций:

MongoClient::   Publisher<ClientSession> startSession(); // to start a session
ClientSession:: Publisher<Void> commitTransaction(); // to commit the transaction
ClientSession:: Publisher<Void> abortTransaction(); // to abort the transaction
ClientSession:: void close(); // to close the session

Я попытался максимально абстрагировать эти методы в классах Dao / Repository:

public Single<ClientSession> startTransaction();
public Function<T, SingleSource<? extends T>> commitTransaction(AtomicReference<ClientSession> sessionReference);

Однако, чтобы использовать транзакцию, мне все равно нужно сделать следующее:

AtomicReference<ClientSession> sessionReference = new AtomicReference<>();

someRepository.startTransaction() // open session & start transaction
            .flatMap(clientSession -> {
                sessionReference.set(clientSession);
                return someRepository.doStuff();
            }).flatMap(stuff -> someRepository.doMoreStuff())
            .flatMap(someRepository.commitTransaction(sessionReference)) // commit
            .doOnError(throwable -> sessionReference.get().abortTransaction()) // rollback
            .doFinally(() -> sessionReference.get().close()) // close session
            .subscribe();

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

Есть ли способ сделать это менее избыточным?

Например, можно ли извлечь три вызова для фиксации / закрытия / отката транзакции в один повторно используемый?

Еще лучше было бы, если бы он также мог включать в себя материал для запуска и сохранения сеанса / транзакции, но у меня нет хорошей идеи, как заставить эту работу в реактивном мире (кроме введения DTO, который всегда будет пройдено по всей цепочке).

...