Spring boot Spring集成:在my Message flow IntegrationFlowBuilder中启动新事务,以提交更改并恢复外部事务

Spring boot Spring集成:在my Message flow IntegrationFlowBuilder中启动新事务,以提交更改并恢复外部事务,spring-boot,spring-integration,spring-transactions,spring-integration-dsl,spring-dsl,Spring Boot,Spring Integration,Spring Transactions,Spring Integration Dsl,Spring Dsl,My jdbcSourceMessage一次执行一批100行的select for update。 在事务中执行integrationFlow时,为获取的批处理保留对数据库的锁定。 我想在消息流中为我的JdbcSourceUpdate启动一个新事务,以执行更新并提交对每个事务的更改 通过通道发送的行 @Bean public IntegrationFlow integrationFlow() { IntegrationFlowBuilder flowBuilder = Integrati

My jdbcSourceMessage一次执行一批100行的select for update。 在事务中执行integrationFlow时,为获取的批处理保留对数据库的锁定。 我想在消息流中为我的JdbcSourceUpdate启动一个新事务,以执行更新并提交对每个事务的更改 通过通道发送的行

@Bean
public IntegrationFlow integrationFlow() {
    IntegrationFlowBuilder flowBuilder = IntegrationFlows.from(jdbcSourceMessage());
    flowBuilder
            .split()
            .log(LoggingHandler.Level.INFO, message ->
                    message.getHeaders().get("sequenceNumber")
                            + " événements publiés sur le bus de message sur "
                            + message.getHeaders().get("sequenceSize")
                            + " événements lus (lot)")
            .transform(Transformers.toJson())
            .log()
            .enrichHeaders(h -> h.headerExpression("type", "payload.typ_evenement"))
            .publishSubscribeChannel(publishSubscribeSpec -> publishSubscribeSpec
            .subscribe(flow -> flow
                    .bridge()
                    .transform(Transformers.toJson())
                    .transform(kafkaGuyTransformer())
                    .channel(this.rabbitMQchannel.demandeInscriptionOutput())) 
            .subscribe(flow -> flow
                    .handle(jdbcMessageHandler())) 
    );
    return flowBuilder.get();
}


@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata defaultPoller() {
    PeriodicTrigger trigger = new PeriodicTrigger(this.proprietesSourceJdbc.getTriggerDelay(), TimeUnit.SECONDS);
    PollerMetadata pollerMetadata = Pollers.trigger(trigger)
            .advice(transactionInterceptor())
            .get();
    pollerMetadata.setMaxMessagesPerPoll(proprietesSourceJdbc.getMaxRowsPerPoll());
    return pollerMetadata;
}

@Bean
public JdbcSourceUpdate jdbcSourceUpdate() {
    return new JdbcSourceUpdate();
}

public TransactionInterceptor transactionInterceptor() {
    return new TransactionInterceptorBuilder()
            .transactionManager(transactionManager())
            .build();
}

public PlatformTransactionManager transactionManager(){
    DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(sourceDeDonnees);
    transactionManager.setRollbackOnCommitFailure(false);
    return transactionManager;
}


public class KafkaGuyTransformer implements GenericTransformer<Message, Message> {

    @Override
    public Message transform(Message message) {
        Message<String> msg = null;
        try {
            DemandeRecueDTO dto = objectMapper.readValue(message.getPayload().toString(), DemandeRecueDTO.class);
            msg = MessageBuilder.withPayload(dto.getTxtDonnee())
                    .copyHeaders(message.getHeaders())
                    .build();
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }
        return msg;
    }
}

public class JdbcSourceUpdate implements MessageHandler {
    @Override
    public void handleMessage(Message<?> message) throws MessagingException {
        try {
            Thread.sleep(100);
            DemandeRecueDTO dto = objectMapper.readValue(message.getPayload().toString(), DemandeRecueDTO.class);
            jdbcTemplate.update(proprietesSourceJdbc.getUpdate(), dto.getIdEvenementDemandeCrcd());
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }
    }
}
既然您有了JdbcSourceUpdate实现,这样做就足够了:

@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void handleMessage(Message<?> message) throws MessagingException {
                        .subscribe(f -> f
                                .gateway(subFlow ->
                                        subFlow.channel(c -> c.executor())
                                                .handle(jdbcMessageHandler()))
                                .channel("nullChannel")
                        ));
所以,听起来DataSourceTransactionManager不适用于暂停。我建议您考虑使用一个.jdcSucCuePoto.Access,但是使用ExcutoRealChanway。这样,handlejdbcSourceUpdate将在新线程上执行,因此将使用新事务执行。主流将等待来自保持其事务打开的网关的回复

大概是这样的:

@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void handleMessage(Message<?> message) throws MessagingException {
                        .subscribe(f -> f
                                .gateway(subFlow ->
                                        subFlow.channel(c -> c.executor())
                                                .handle(jdbcMessageHandler()))
                                .channel("nullChannel")
                        ));

购买JdbcSourceUpdate必须为网关回复返回一些内容。考虑不要在那里实现MessageHandler,但只需用一个单一的非空洞方法来做一个普通的POJO。< /P>它与HealLeJdBCaseCuppEDATE、E-> E.TraceActualTror相同,具有以下配置“公共事务拦截程序事务拦截程序”{返回新TransactionInterceptorBuilder.transactionManagertransactionManager.propagationPropagation.REQUIRES_new.build;}```几乎可以,但transactionaltrue不会传播。REQUIRES_NEW。您应该使用重载变量:transactionalTransactionInterceptor依赖TransactionInterceptorBuilder及其选项。事实上,我已经尝试了这两种方法并尝试了注释。JdbcSourceUpdate仍然没有提交更新。请参阅我的文档中的更新请回答。谢谢阿泰姆,你能举个例子吗?对不起,我对SI不太了解。