Spring AMQP
  1. Spring AMQP
  2. AMQP-190

CachingConnectionFactory leaks channels when synchronized with a TransactionManager

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Complete
    • Affects Version/s: 1.0.0 GA
    • Fix Version/s: 1.1.2, 1.2.0.M1
    • Component/s: RabbitMQ
    • Labels:

      Description

      It seems that when I use RabbitTemplate, channelTransacted=true, to convertAndSend() a message to an exchange within the context of a synchronized TransactionManager (e.g. an active transaction on the current thread), the channel is never closed, hence new publishes will always get their "own", shiny, new channel (that is never closed or released to the channel pool) until Rabbit can't handle any more channels.

      See Forum Reference for more info.

      The problem is not observed on the consumer side (e.g. MessageListenerContainer). Its observed on the publishing side, (e.g. RabbitTemplate). It is observed both if I use the RabbitTemplate, natively... or if I use spring-integration and the <int-amqp:outbound-channel-adapter...> tag.

      BTW, the observed "channel leak" goes away when I choose channelTransacted=false.

      I will look to supply a simple recreate, if I can scrounge the time.

        Activity

        Hide
        Rene Parra added a comment -

        CachingConnectionFactory.reset() is protected.

        Show
        Rene Parra added a comment - CachingConnectionFactory.reset() is protected.
        Hide
        Dave Syer added a comment -

        I'm not sure which line you are uncommenting. Does the fix I proposed work for you or not?

        Sorry about the protected method - you will have to extend to expose it publicly I guess.

        Show
        Dave Syer added a comment - I'm not sure which line you are uncommenting. Does the fix I proposed work for you or not? Sorry about the protected method - you will have to extend to expose it publicly I guess.
        Show
        Rene Parra added a comment - Yes. The fix works. The commented line I am referring to is this one: https://fisheye.springsource.org/browse/spring-amqp/spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/ConnectionFactoryUtils.java?r=7538a6072b2a0f9668ab5981bcdaadd1719e9132#to253 If this is uncommented, it works.
        Hide
        Rene Parra added a comment -

        For the workaround, I am using an @Aspect.

        /**
         * Aspect for patching ConnectionFactoryUtils so that channels are not leaked within the context of a transaction
         * @author René X. Parra
         */
        @Aspect
        public class AMQP190Patch {
            @Around(value="execution(void org.springframework.amqp.rabbit.connection..*.afterCompletion(..))", argNames="pjp")
            public void patchAmqp190(ProceedingJoinPoint pjp) throws Throwable {
                Field field = FieldUtils.getField(pjp.getTarget().getClass(), "resourceHolder", true);
                RabbitResourceHolder resourceHolder = (RabbitResourceHolder) field.get(pjp.getTarget()); 
                resourceHolder.setSynchronizedWithTransaction(false);
                pjp.proceed();
            }
        }
        

        Thanks again Dave!!!

        Show
        Rene Parra added a comment - For the workaround, I am using an @Aspect. /** * Aspect for patching ConnectionFactoryUtils so that channels are not leaked within the context of a transaction * @author René X. Parra */ @Aspect public class AMQP190Patch { @Around(value= "execution(void org.springframework.amqp.rabbit.connection..*.afterCompletion(..))" , argNames= "pjp" ) public void patchAmqp190(ProceedingJoinPoint pjp) throws Throwable { Field field = FieldUtils.getField(pjp.getTarget().getClass(), "resourceHolder" , true ); RabbitResourceHolder resourceHolder = (RabbitResourceHolder) field.get(pjp.getTarget()); resourceHolder.setSynchronizedWithTransaction( false ); pjp.proceed(); } } Thanks again Dave!!!
        Hide
        Gary Russell added a comment -

        Still an issue; see

        https://github.com/SpringSource/spring-amqp/commit/7538a6072b2a0f9668ab5981bcdaadd1719e9132#commitcomment-1413088

        I repro'd the issue with a mock test; when running in a tx, the channel is not returned to the pool.

        Show
        Gary Russell added a comment - Still an issue; see https://github.com/SpringSource/spring-amqp/commit/7538a6072b2a0f9668ab5981bcdaadd1719e9132#commitcomment-1413088 I repro'd the issue with a mock test; when running in a tx, the channel is not returned to the pool.

          People

          • Assignee:
            Gary Russell
            Reporter:
            Rene Parra
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: