реактивный драйвер 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, который всегда будет пройдено по всей цепочке).