I have an app that uses Hibernate and AMQP. The transaction manager is configured as :
I then have the following:Code:<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory" p:dataSource-ref="dataSource" />
My listener receives a message and delegates to a service which creates some data and saves it in the DB. The method that is called is annotated with @Transactional. What I want to know is, say the call to save() completes without any issues and so does the handleMessage() method in the listener, but somewhere higher up in the execution chain an exception is encountered and the message is never acknowledged. Will this exception cause the work in the save() method to be rolled back? If the broker never receives the acknowledgement, it will resend the message causing possible duplicate data to be saved. Another example is, say that the save() and handle() methods complete without any issues, but before the message is acknowledged, the app goes down for some reason. Again this will cause the broker to resend the message (the queue is durable using a topic exchange). Should I worry about this scenario?Code:@Configuration public class MyConfig { @Resource(name="transactionManager") private PlatformTransactionManager txManager; @Autowired private MyListener messageListener; @Bean public SimpleMessageListenerContainer mySMLC() { final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(); container.setConnectionFactory(rabbitConnectionFactory); container.setQueueNames("myQueue"); final MessageListenerAdapter adapter = new MessageListenerAdapter(messageListener); adapter.setMessageConverter(converter); container.setMessageListener(adapter); container.setChannelTransacted(true); container.setTransactionManager(txManager); return container; } ... @Component public class MyListener { @Resource(name="myServiceImpl") private MyService service; public void handleMessage(MyDTO convertedMessage){ Resource r = new Resource(convertedMessage.getCategory()); ... // set some other properties on r service.save(r); // this is more complicated in the real code } } ... @Service public class MyServiceImpl implements MyService { @Override @Transactional public void save(Resource resource){ // do some work and save to DB } } }


Reply With Quote
