Uploaded image for project: 'Spring AMQP'
  1. Spring AMQP
  2. AMQP-796

commitIfNecessary behavior RabbitTemplate with its channelTransacted=true

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Complete
    • Affects Version/s: 2.0.1
    • Fix Version/s: 1.7.6, 2.0.2
    • Component/s: RabbitMQ
    • Labels:
    • Environment:
      RabbitMQ 3.7.2, Erlang 20.2

      Description

      We use the following configuration:

      ApplicationConfig.java
      	@Bean
      	public ConnectionFactory connectionFactory() {
      		CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
      		connectionFactory.setUsername("guest");
      		connectionFactory.setPassword("guest");
      		connectionFactory.setPort(5672);
      
      		return connectionFactory;
      	}
      
      	@Bean
      	public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
      		RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
      		rabbitTemplate.setChannelTransacted(true);
      		rabbitTemplate.setExchange("MyOwnExchange");
      
      		return rabbitTemplate;
      	}
      

      We have the following case:
      We publish an event to RabbitMQ with the Rabbittemplate.isChannelTransacted set to true.
      The Exchange were we send the event to does not exists on our RabbitMQ server so we expect an error like: "reply-code=404, reply-text=NOT_FOUND - no exchange 'MyOwnExchange' in vhost '/'"

      In my case, a post to my RestController.add methode leads to an event being published to RabbitMQ. The first time I do an post to this add methode, an exception is returned as expected because inside the RabbitTemplate.doSend(...) the _"RabbitUtils.commitIfNecessary(channel);" _gets called and throws an exception on the channel because the Exchange in Rabbit does not exists.
      But when I do the post to my RestController.add methode again, I actually get an 201 response. This time the "RabbitUtils.commitIfNecessary(channel);" is not called and the exception is not returned in the controller. Only in the TransactionSynchronization.afterCompletion, the channel error will popup.

      It seems that only the first time the RabbitTemplate sees the channel as "locallyTransacted" and commits it at the end of the doSend(..) methode.
      Is this behavior as expected
      If yes, can we enforce the RabbitTemplate to always use a Channel that is locallyTransacted
      We are trying to achieve that the RabbitTemplate commits after every event send to RabbitMQ, so we can act on error before our RestController completes the response.

      I created an example project(see attachment) which represents our actual case. I added an integration-test which reproduces the problem/behavior.
      Before running the test in "PublishToUnknownExchangeTest" you need to have RabbitMQ running on localhost:5672 with user:guest and pass:guest(or change the ApplicationConfig.java).

        Attachments

          Activity

            People

            • Assignee:
              grussell Gary Russell
              Reporter:
              r.de.haard@everest.nl Raoul de Haard
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: