从处理程序回滚消息到通道

时间:2014-06-09 17:17:15

标签: spring-integration

我正在尝试为将在我的SI流中使用的所有消息处理程序创建一个通用的错误处理过程。这将, 1.重试连接异常。 2.使用断路器停止SI流量。 3.将失败的消息回滚到通道。

我已经实现了重试和断路功能。但是,我无法将消息回滚到频道。 我尝试使用交易建议。但它不起作用。

这是代码。

<bean id="retryAdvice"
    class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
    <property name="retryTemplate">
        <bean class="org.springframework.retry.support.RetryTemplate">
            <property name="backOffPolicy">
                <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
                    <property name="initialInterval" value="2000" />
                    <property name="multiplier" value="2" />
                </bean>
            </property>
        </bean>
    </property>
    <property name="recoveryCallback">
        <bean
            class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
            <constructor-arg ref="recoveryChannel" />
        </bean>
    </property>
    <property name="retryStateGenerator">
        <bean
            class="org.springframework.integration.handler.advice.SpelExpressionRetryStateGenerator">
            <constructor-arg value="headers['uniqueId']" />
        </bean>
    </property>
</bean>

<int:channel id="recoveryChannel" />
<int:transformer id="defaultTransformer" input-channel="recoveryChannel"
    output-channel="loggerChannel" ref="defaultTransformer" method="transform">
</int:transformer>

<int:logging-channel-adapter id="loggerChannel"
    level="INFO" log-full-message="true" auto-startup="true">
</int:logging-channel-adapter>

<bean id="defaultTransformer"
    class="com.bestbuy.ingestion.foundation.core.util.DefaultTransformer" />

<bean id="circuitBreakerAdvice"
    class="org.springframework.integration.handler.advice.RequestHandlerCircuitBreakerAdvice">
    <property name="threshold" value="2" />             <!-- close after 2 failures -->
    <property name="halfOpenAfter" value="60000" />     <!-- half open after 15 seconds -->
</bean>

<tx:advice id="txansactionAdvice" transaction-manager="transactionManager">
</tx:advice>

我需要使用哪种类型的事务管理器。 我可能在不同的数据源上使用不同的消息处理程序。

以下是我如何将这些建议添加到消息处理程序。

public Object postProcessBeforeInitialization(Object bean, String beanName)
        throws BeansException {

    logger.error("called for bean id :: "+beanName+" with bean class "+bean.getClass().getName());
    if(bean instanceof AbstractSimpleMessageHandlerFactoryBean){
        logger.error("************ Bean "+beanName+" is instance of AbstractSimpleMessageHandlerFactoryBean **********");
    }
    if(bean instanceof ConsumerEndpointFactoryBean){
        logger.error("Bean is of type ConsumerEndpointFactoryBean");
        return populateRequestHandlerAdviceChain((ConsumerEndpointFactoryBean)bean);
    }
    if(bean instanceof AbstractSimpleMessageHandlerFactoryBean){
        logger.error("Bean is of type AbstractSimpleMessageHandlerFactoryBean");
        return populateRequestHandlerAdviceChain((AbstractSimpleMessageHandlerFactoryBean<?>)bean);
    }
    return bean;
}
private Object populateRequestHandlerAdviceChain(ConsumerEndpointFactoryBean bean){
    ArrayList<Advice> list = new ArrayList<Advice>();
    logger.error("Adding Retry Advice");
    list.add((Advice)factory.getBean("retryAdvice"));
    logger.error("Adding Cricuit Breaker Advice");
    list.add((Advice)factory.getBean("circuitBreakerAdvice"));
    logger.error("Adding Transactional Advice");
    list.add((Advice)factory.getBean("txansactionAdvice"));
    bean.setAdviceChain(list);
    return bean;
}

如果ConsumerEndpointFactoryBean类型的bean我添加了这些建议。我需要在所有这些处理程序中进行事务管理。

1 个答案:

答案 0 :(得分:0)

首先:由于您的txansactionAdvice嵌套在retryAdvice,因此您在此处重新开始重试。

另一方面,不清楚为何每次重试都应用circuitBreakerAdvice。我会说这种模式会更好地使用'around'retryAdvice

txansactionAdvice应排在最前面。所以,它可能看起来像这样:

txansactionAdvice
circuitBreakerAdvice
retryAdvice

还有一点:您的交易不会被回滚,因为您使用recoveryCallback,只会发送ErrorMessage并扼杀异常。

HTH,你会改变主意。