I’m implementing Transactional Outbox pattern using Java. The Message Relay Service will poll the Outbox table for entries, and after an outbox message is found and processed, it will update the Outbox entry to be “processed”. I’m using Spring Boot and ran into Spring Integration project and wonder if this is a good way for this pattern to handle the Message Relay polling and JPA updates to the Outbox table or are there better ways?
EDIT 1:
I`m trying to set up the JpaOundboundGateway. Is this correct? And how can I set the parameter to the Jpa Query?
@Bean public JpaExecutor jpaUpdateStateExecutor() { JpaExecutor jpaExecutor = new JpaExecutor(this.entityManagerFactory); jpaExecutor.setNamedQuery("myQuery"); jpaExecutor.setUsePayloadAsParameterSource(true); jpaExecutor.setExpectSingleResult(true); return jpaExecutor; } @Bean @ServiceActivator(inputChannel = "jpaChannel") public MessageHandler jpaOutbound() { JpaOutboundGateway gateway = new JpaOutboundGateway(jpaUpdateStateExecutor()); gateway.setGatewayType(OutboundGatewayType.UPDATING); return gateway; }
My Gateway:
@MessagingGateway public interface MyGateway { @Gateway(requestChannel = "jpaChannel") @Transactional void jpaActions(Long idOfEntity); }
Advertisement
Answer
That’s exactly what Spring Integration is for.
You probably may consider to use a JdbcChannelMessageStore
and a QueueChannel
based in it. So, one service would send a message to this channel within its transaction. On the other side there is going to be a polling consumer to read from that channel, and therefore your messages table. NOTE: this solution removes messages from the INT_CHANNEL_MESSAGE
table in the end of poll transaction.
You may consider to use a JPA Outbound Channel Adapter to persist message on one side and JPA Polling Channel Adpater on the other side to update the entity.
See more in docs: https://docs.spring.io/spring-integration/docs/current/reference/html/jpa.html#jpa
Either way I don’t see problems in implementing that pattern with Spring Integration.