Привет,
мы продолжаем оценивать Hibernate Reactive для замены нашего текущего программного обеспечения, состоящего из postgres-db+spring boot+spring data+r2dbc. Мы столкнулись со многими ограничениями при использовании r2dbc и хотели повторно использовать обширные знания, которые у нас уже есть о Hibernate.
Мы почти полностью переработали микросервис, переписали собственные spring-данные (общий репозиторий), и это выглядит очень хорошо.
Одна из основных проблем, которую разработчики поднимают, связана с возможностью использования декларативного управления транзакциями (с использованием аннотаций) вместо программного.
Мы знаем, что целью Hibernate reactive является не реализация такого механизма, а фреймворки (Spring, Quarkus...), которые интегрируются с Hibernate, как это было сделано для стандартного Hibernate. Даже если мы хотим сделать это самостоятельно, API транзакций в Hibernate reactive отличается от стандартного API Hibernate, и нет API для взаимодействия с менеджером транзакций.
Я буду рад, если мы сможем получить ваши комментарии по этому поводу (и даже больше, если вы можете :smiley:), и если вы все еще думаете, что мы можем это сделать, чтобы предложить общие рекомендации, потому что в настоящее время мы понятия не имеем, как это сделать.
Спасибо
Ну, я полагаю, что в Spring есть какая-то концепция перехватчика, в которой вы можете использовать аннотации для привязки перехватчика к вызову метода компонента. Если вы вызываете withTransaction()
из такого перехватчика, а затем делегируете его методу bean-компонента, это все декларативное управление транзакциями. На самом деле это должно быть всего несколько строк кода. (По крайней мере, это было бы в CDI, я менее уверен в весне.)
Единственная тонкость заключается в том, что вам нужен способ определить, есть ли транзакция, уже привязанная к текущему реактивному потоку. В нашем стеке это можно было бы сделать с помощью MP Contexts. Понятия не имею, как это делается в Стране Спринг.
(OTOH, если вы спрашиваете о том, как интегрироваться с менеджером транзакций XA, ну, это совершенно другая проблема, и сейчас это не очень практично с реактивным драйвером. У нас еще нет по-настоящему реактивной транзакции менеджеры.)
Прямо сейчас нам не нужна распределенная транзакция
Тогда перехватчик, который вызывает SessionFactory.withTransaction()
, должен работать нормально.
Попробую так и обновлю. Спасибо
@gavinking похоже, что Spring реализует @Transactional с использованием Aspect. На самом деле это не так важно, но нам может быть проще реализовать.
Но я думаю, что мы не сможем сделать это, только если вы предоставите API для openTransaction() commitTransaction() и rollbackTransaction() в классе Stage, поскольку у нас есть API openSession() и closeSession(). Я думаю, что объект транзакции нужен, а withTransaction недостаточно.
Имеет ли это смысл ?
Должно быть какое-то понятие перехватчика «вокруг», которое позволяет вам обернуть и перенаправить метод.
(Это правда, что вы не можете сделать это с перехватчиками до/после.)
Я думаю, что это: https://howtodoinjava.com/spring-aop/aspectj-around-annotation-example/
@gavinking , не могли бы вы рассказать о том, что вы написали ранее: «В нашем стеке это будет сделано с использованием контекстов MP». проверить, привязана ли уже транзакция в текущем потоке? Можете ли вы сослаться на код или тесты, которые были написаны. То же самое для сеанса, как я могу понять, что сеанс уже открыт в текущем потоке.
Спасибо.
Слушай, я понятия не имею, как ты делаешь это весной. Вам нужна какая-то конструкция, похожая на threadlocal, но локальная, привязанная к текущему реактивному потоку, а не к потоку. Я уверен, что у них должно быть что-то.
В настоящее время я не собираюсь использовать Spring @Transactional, но реализую нашу собственную транзакционную аннотацию, чтобы не слишком углубляться в Spring. Итак, мой предыдущий вопрос был связан с вашим предложением «В нашем стеке это будет сделано с использованием контекстов MP».
"наш стек" == Quarkus.
Я говорю, что вы должны найти что-то подобное в среде Spring.
Потому что, если вы не можете привязать значение к текущему реактивному потоку, то у вас не может быть декларативных транзакций, таких простых, и вам просто придется управлять транзакциями «вручную». (Что на самом деле очень просто, просто вызывая withTransaction()
. Я действительно не понимаю, почему люди думают, что им нужна аннотация для этого.)
Но я уверен, что должен быть какой-то способ сделать это. Вы просто спрашиваете не того человека.
Может быть, это дело, но я действительно не знаю https://projectreactor.io/docs/core/3.4.0-M1/api/index.html?reactor/util/context/Context.html
Может быть, это? https://www.baeldung.com/spring-transaction-active
Закрытие: заменено #782.
@yaakov-berkovitch с тем, что я внедряю в # 779, вам должно быть еще проще реализовать это.
@gavinking Спасибо!!