I need to synchronize a message reception, saving in a database and sending of another message, all in a single transaction. I'm using Spring Boot and relying on its autoconfiguration. The message broker is Active MQ.
For my use case it's enough with best effort 1 phase commit, so I've configured a ChainedTransactionManager
:
@EnableTransactionManagement
@Configuration
public class TransactionConfiguration {
@Bean
public PlatformTransactionManager chainedTransactionManager(DataSourceTransactionManager dtm,
JmsTransactionManager jtm) {
return new ChainedTransactionManager(jtm, dtm);
}
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public JmsTransactionManager jmsTransactionManager(ConnectionFactory connectionFactory) {
return new JmsTransactionManager(connectionFactory);
}
}
The application flow would be something like this:
private final JmsTemplate jmsTemplate;
private final MessageRepository messageRepository;
@Transactional
@JmsListener(destination = "someDestination")
public void process(Message message){
jmsTemplate.isSessionTransacted();
//Save to DB
messageRepository.save(message);
//Send to another queue
jmsTemplate.convertAndSend("anotherDestination", new ProcessedMessage(message));
}
Inside the process()
method I've seen that jmsTemplate.isSessionTransacted();
is false
.
Do I need to explicitly configure a
JmsTemplate
bean withsetSessionTransacted(true)
or it is enough with my current transaction configuration?What's the difference between configuring
JmsTemplate.setSessionTransacted(true)
and the usage ofChainedTransactionManager
+JmsTransactionManager
?