My jdbcSourceMessage execute a select for update with batch of 100 rows at a time. While the integrationFlow is been executed in a Transaction to hold a lock to the database for the fetched batch. I would like to start new Transaction for my JdbcSourceUpdate (within the message flow) to excute an update and commit my change for each row sent throught the channel.
@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);
}
}
}