spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.18k stars 40.68k forks source link

RabbitAutoConfiguration does not have properties for channel transacted #11821

Open m-van-tilburg opened 6 years ago

m-van-tilburg commented 6 years ago

Spring Boot version: 1.5.9.RELEASE

Spring Boot autoconfiguration for RabbitMQ does not have properties to make the channels of the underlying RabbitTemplate transactional. A workaround is needed to enable it anyway. We did this by implementing a custom BeanPostProcessor

private static class RabbitTransactedBeanPostProcessor implements BeanPostProcessor {

    /**
     * Make RabitTemplate channel transacted because RabbitAutoConfiguration does not allow to set this
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      if (bean instanceof RabbitTemplate) {
        RabbitTemplate rabbitTemplate = (RabbitTemplate) bean;
        rabbitTemplate.setChannelTransacted(true);
      }

      return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      return bean;
    }
  }

It is of course also possible to override the RabbitTemplate bean definition, but this would require duplication of the property handling logic. Could you add support for making the Rabbit channel transacted in RabbitAutoConfiguration and RabbitProperties?

snicoll commented 6 years ago

See https://github.com/spring-projects/spring-boot/pull/10978#issuecomment-350976476

m-van-tilburg commented 6 years ago

Can we safely assume that the channelTransacted property will be merged with #10978 ? Because the title is only about 'exchange and routingKey'.

snicoll commented 6 years ago

That issue is closed and it won't be merged no. The reason for the comment is to link this issue to the discussion that we had there.

(If it was a duplicate, this issue would have been closed already).

m-van-tilburg commented 6 years ago

For our use case we only publish messages to the queue. @garyrussell Would you expect different Spring Boot properties to make the message listener and/or the message producer transactional?

garyrussell commented 6 years ago

@m-van-tilburg @snicoll and I had a discussion about that; the referenced PR added it for the template only; my objection was that we should also add a flag for consumers; my preference was 2 flags but Stephane's preference was a single flag that applied to both. The most common use case is where a consumer starts the transaction and messages published participate in the same transaction. He rightly pointed out that the corner case of using a non-transactional template with a transactional consumer (e.g. audit logging regardless of success/failure) would require a separately wired up template anyhow.

In the end, he removed that property while polishing the PR.

m-van-tilburg commented 6 years ago

@garyrussell Can we expect a property to make the (producer) channel transactional? It seems a bit strange that to enable any transactional behaviour, a custom Properties class and RabbitTemplate bean definition is needed.