Управление декларативными транзакциями в Spring ведет себя непредсказуемо - PullRequest
0 голосов
/ 02 сентября 2011

У меня есть приложение Spring + Hibernate с декларативным управлением транзакциями.У меня есть сервис (FooService), который имеет 2 открытых метода MethodA и MethodB.Клиент будет call MethodA, который в свою очередь вызовет MethodB.

Client -> MethodA -> MethodB

Я хочу, чтобы транзакция начиналась только с MethodB и далее.Это фрагмент моего весеннего контекста приложения:

<bean id="FooService"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager" />
    <property name="target" ref="FooServiceTarget" />
    <property name="transactionAttributes">
      <props>
        <prop key="MethodB">PROPAGATION_REQUIRED,-FooException</prop>
      </props>
   </property>
</bean>

Однако, когда я вызываю MethodA из моего клиента, он не создает прокси транзакции, когда MethodB должен быть вызван.Если я добавлю MethodA также к конфигурации компонента в контексте приложения, будет запущен прокси транзакции (начиная с MethodA, как и ожидалось).Почему это так?Могу ли я достичь транзакции, созданной только из MethodB и далее?

Ответы [ 2 ]

2 голосов
/ 02 сентября 2011

Могу ли я получить транзакцию, созданную только из MethodB и далее?

Только если вы используете переплетение байт-кода AspectJ с Spring .

Почему это так?

По умолчанию SpringМеханизм AOP - это JDK динамические прокси , который создает отдельный экземпляр Proxy, который реализует ваш интерфейс службы.Этот прокси-сервер внедряется в другой компонент вместо вашего сервиса, и все вызовы, которые проходят через него, будут выполнять транзакции перед передачей в ваш сервис.Поскольку звонок от вашего сервиса к себе не проходит через прокси, никакая транзакция не может или не будет начата.При переплетении байт-кода AspectJ код транзакции будет вплетен непосредственно в ваш сервис, и он будет работать нормально.Однако, если вам это нужно для этой цели, стоит посоветовать вам реорганизовать вашу «услугу» как минимум в два отдельных объекта, потому что это сигнал о том, что вы смешали проблемы и / или пересекли уровни абстракции водин класс.

2 голосов
/ 02 сентября 2011

Клиент -> Метод A -> Метод B

Я хочу, чтобы транзакция начиналась только с MethodB и далее

Это не может работать.Метод A и метод B находятся внутри одного и того же прокси.

Единственное, что нужно сделать, это переместить метод B в другой Бин.

Кстати: об этом уже много раз спрашивали, здесьВот несколько моих предыдущих ответов:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...