Параллельные запросы с реактивным Panache
Из https://github.com/quarkusio/quarkus/issues/32790 и связанного объяснения я понимаю, что вы не можете повторно использовать сеанс в параллельных системах. Насколько я понимаю, вы сможете достичь параллельного аспекта, проводя разные сеансы для каждого Uni.
Однако как это должно работать с Panache? Представьте себе следующий пример (у меня есть другой с двумя разнымиPanacheQuery
работают параллельно, но это проще рассмотреть без особого контекста):
@WithSession
public Uni<SearchSessionsResult> search(...) {
final PanacheQuery<Session> query = this.find(logic with the received parameters)
return Uni.combine()
.all()
.unis(
query.list(),
query.pageCount(),
query.count()
)
.combinedWith(entities, pageCount, totalEntries) -> [some more business logic]);
}
Это не удастся сjava.lang.IllegalStateException: Illegal pop() with non-matching JdbcValuesSourceProcessingState
из-за того, что три устройства работают параллельно, что и ожидалось. Поскольку объединение трех юнитов в цепочку немного непрактично, а последовательное выполнение действий может иметь большой эффект, если у вас большее количество юнитов (и/или они более сложные), я хотел следовать подходу, заключающемуся в том, чтобы каждый юниор запускался с отдельным сеансом. , но я не уверен, как этого добиться, придерживаясь Panache.
Я попробовал обернуть юниты с помощьюPanache.withSession
, вот так:
@WithSession
public Uni<SearchSessionsResult> search(...) {
final PanacheQuery<Session> query = this.find(logic with the received parameters)
return Uni.combine()
.all()
.unis(
Panache.withSession(query::list),
Panache.withSession(query::pageCount),
Panache.withSession(query::count)
)
.combinedWith(entities, pageCount, totalEntries) -> [some more business logic]);
}
Но результат тот же, потому что Panache будет повторно использовать текущий открытый реактивный сеанс для всех устройств. Я также попробовал ввестиSessionFactory
и сам открываю сессии (признаюсь, я не слишком много знаю о том, как это сделать, но я старался следовать логике вPanache
класс открытия сеанса и последующего связывания универа)
@Inject
SessionFactory sessionFactory;
@WithSession
public Uni<SearchSessionsResult> search(...) {
final PanacheQuery<Session> query = this.find(logic with the received parameters)
return Uni.combine()
.all()
.unis(
sessionFactory.openSession().chain(session -> query.list().eventually(session::close)),
sessionFactory.openSession().chain(session -> query.pageCount().eventually(session::close)),
sessionFactory.openSession().chain(session -> query.count().eventually(session::close))
)
.combinedWith(entities, pageCount, totalEntries) -> [some more business logic]);
}
И получил тот же результат. Итак, вопрос, по сути, прост: как я могу выполнять несколько запросов к БД параллельно с помощью Panache? ПРИМЕЧАНИЕ. Первый пример работал в Quarkus 2.