Spring boot Spring集成:在my Message flow IntegrationFlowBuilder中启动新事务,以提交更改并恢复外部事务
My jdbcSourceMessage一次执行一批100行的select for update。 在事务中执行integrationFlow时,为获取的批处理保留对数据库的锁定。 我想在消息流中为我的JdbcSourceUpdate启动一个新事务,以执行更新并提交对每个事务的更改 通过通道发送的行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
@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不太了解。