2013-09-19 3 views
4

Inboud шлюза:держать сделку в течение весны интеграции поток

<int-http:inbound-gateway id="inbound.gateway" 
          request-channel="transactional.channel.input" 
          reply-channel="channel.output" 
          error-channel="channel.error" 
          request-payload-type="java.lang.String" 
</int-http:inbound-gateway> 

Advice определение:

<tx:advice id="advice"> 
    <tx:attributes> 
     <tx:method name="send" propagation="REQUIRES_NEW" rollback-for="MyClassException"/> 
    </tx:attributes> 
</tx:advice> 

Рекомендация конфигурация:

<aop:config> 
    <aop:advisor advice-ref="advice" pointcut="bean(transactional.channel.input)"/> 
</aop:config> 

цепь, которая должна быть транзакционными:

<int:chain input-channel="transactional.channel.input" output-channel="non.transactional.channel.input> 
    <int:service-activator ref="v1.registerUser.service" method="registerUser"/> 
    <int:service-activator ref="v1.saveObject.service" method="saveObject"/> 
</int:chain> 

цепи, которая нуждается в транзакции должна быть выполнена ранее, чтобы получить идентификатор объекта генерируется в последнем transational шага цепи:

<int:chain input-channel="non.transactional.channel.input" output-channel="channel.output"> 
    <int:service-activator ref="v1.getObjectId.service" method="getObjectId"/> 
    <int:object-to-json-transformer/> 
</int:chain> 

Имея этот упрощенный контекст, когда доступ к идентификатору в службе getObjectId, сделка не имеет был выполнен.

Таким образом, транзакция, по-видимому, совершается на выходном уровне входящего-шлюза.

+0

Это зависит о том, как начинается ваш поток - что у вас есть перед v1.getEvent.channel.input? –

+0

У меня есть входящий-шлюз, подключенный к одной цепочке, и у этого есть 'v1.getEvent.channel.input' в качестве выходного канала так:' (inbound-gateway) '->' (chain) '->' (код I выложили) ' –

ответ

9

Один удивительный трюк без написания кода на Java:

<channel id="input"/> 

<aop:config> 
    <aop:advisor advice-ref="txAdvice" pointcut="bean(input)"/> 
</aop:config> 

<tx:advice id="txAdvice"> 
    <tx:attributes> 
    <tx:method name="send"/> 
    </tx:attributes> 
</tx:advice> 

С этим все ваши прямые singlethreaded поток сообщений будет обернут в TX на отправки сообщения на канал вход

+0

Я пробовал и работает как шарм! Спасибо artem :) –

+0

Привет, Артем. Вернемся к этой теме, чтобы убедиться. Я использую этот подход с каналом ввода цепочки, поэтому фиксация транзакции будет сделана, когда цепочка будет закончена, правильно? Потому что я понял, и идентификатор объекта имеет значение null, когда я его прошу сохранить, но он сохраняется правильно в БД. –

+1

Правильно, потому что все остальные 'send' для каналов базовой цепочки выполняются в потоке вашего канала' input'. –

4

Если это код MessagingGateway, введенный в ваш код, вы можете просто начать транзакцию у шлюза, и, поскольку все каналы являются прямыми, весь поток будет работать в одной транзакции. Просто аннотируйте свой метод шлюза с помощью @Transactional и добавьте <tx:annotation-driven/> или @EnableTransactionManagement в свой контекст (и диспетчер транзакций).

Или вы можете начать транзакцию даже раньше, если вы хотите другие вещи в сделке ...

@Transactional 
public void foo() { 
    ... 
    Object reply = myGateway.exchange(Object foo); 
    ... 
} 

Просто убедитесь, что для вызова foo() из другого бина, так что класс, содержащий foo() заворачивают в сделке proxy (by @EnableTransactionManagement или <tx:annotation-driven/>).

Если это шлюз, такой как входящий HTTP-шлюз, добавьте шлюз @Transaction после входящего шлюза, чтобы начать транзакцию. (Добавьте сервис-активатор, который ref с a <gateway/>, который обменивается Message<?> и аннотируется @Transactional). более

+0

Спасибо, что ответили Гэри! Я, наконец, выбрал решение Artem, но спасибо в любом случае :) –

Смежные вопросы