Spring Integration - JdbcPollingChannelAdapter提交而不是对已处理的Exceptions进行回滚

时间:2015-08-11 09:44:32

标签: spring spring-integration spring-jdbc spring-java-config

我正在使用Spring 4.1.x APIsSpring Integration 4.1.x APIsSpring Integration Java DSL 1.0.x APIs进行EIP流,我们使用JdbcPollingChannelAdpater作为流入口,从Oracle数据库表中使用消息

即使我们在ErrorHandler的{​​{1}}上配置了JdbcPollingChannelAdapter,我们也看到会话的Poller仍在回滚,而在Transaction时未提交{1}}抛出并正确处理{1}}。

在阅读完这个帖子:Spring Transactions - Prevent rollback after unchecked exceptions (RuntimeException)之后,我感觉不可能阻止回滚而是强制提交。它是否正确?并且,如果有一种方法,在安全处理错误时,最简单的方法是强制提交而不是回滚?

当前配置:

IntegrationConfig.java:

RuntimeException

ErrorHandler.java

ErrorHandler

--- EDITED包括ExpressionEvaluatingRequestHandlerAdvice Bean ---

@Bean
public MessageSource<Object> jdbcMessageSource() {

    JdbcPollingChannelAdapter adapter = new JdbcPollingChannelAdapter(
            dataSource,
            "select * from SERVICE_TABLE where rownum <= 10 for update skip locked");
    adapter.setUpdateSql("delete from SERVICE_TABLE where SERVICE_MESSAGE_ID in (:id)");
    adapter.setRowMapper(serviceMessageRowMapper);
    adapter.setMaxRowsPerPoll(1);
    adapter.setUpdatePerRow(true);
    return adapter;
}

@SuppressWarnings("unchecked")
@Bean
public IntegrationFlow inFlow() {

    return IntegrationFlows
            .from(jdbcMessageSource(),
                    c -> {
                        c.poller(Pollers.fixedRate(100)
                                .maxMessagesPerPoll(10)
                                .transactional(transactionManager)
                                .errorHandler(errorHandler));
                    })
                .channel(inProcessCh()).get();
}

---编辑显示虚拟测试消息处理程序---

@Component
public class ErrorHandler implements org.springframework.util.ErrorHandler {

    @Autowired
    private PlatformTransactionManager transactionManager;

    private static final Logger logger = LogManager.getLogger();

    @Override
    public void handleError(Throwable t) {

        logger.trace("handling error:{}", t.getMessage(), t);

        // handle error code here...

        // we want to force commit the transaction here?
        TransactionStatus txStatus = transactionManager.getTransaction(null);
        transactionManager.commit(txStatus);
    }
}

--- EDITED显示ExecutorChannelInterceptor方法---

@Bean
public Advice expressionEvaluatingRequestHandlerAdvice() {
    ExpressionEvaluatingRequestHandlerAdvice expressionEvaluatingRequestHandlerAdvice = new ExpressionEvaluatingRequestHandlerAdvice();
    expressionEvaluatingRequestHandlerAdvice.setTrapException(true);
    expressionEvaluatingRequestHandlerAdvice.setOnSuccessExpression("payload");
    expressionEvaluatingRequestHandlerAdvice
            .setOnFailureExpression("payload");
    expressionEvaluatingRequestHandlerAdvice.setFailureChannel(errorCh());
    return expressionEvaluatingRequestHandlerAdvice;
}

1 个答案:

答案 0 :(得分:1)

仅仅因为您的import Foundation import CoreData @objc(Dog) class Dog: NSManagedObject { // Insert code here to add functionality to your managed object subclass } 在TX结束后已经正常工作而无效。

以下是几行源代码(ErrorHandler):

AbstractPollingEndpoint.Poller

其中:

  1. @Override public void run() { taskExecutor.execute(new Runnable() { @Override public void run() { ............. try { if (!pollingTask.call()) { break; } count++; } catch (Exception e) { .... } } } }); } 默认适用于ErrorHandlertaskExecutor)。

  2. {li>

    SyncTaskExecutor作为TransactionInterceptor被应用于Aspect周围的代理。

    因此TX在pollingTask附近完成并熄灭。只有在此之后,pollingTask.call()开始在ErrorHandler内工作。

    要解决您的问题,您需要确定哪个下游流程部分对于TX rallback不是那么重要,并使某些taskExecutor.execute()或使用try...catch来“掩盖”{{1} }。

    但正如你已经注意到我必须在 TX内完成