This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

AnnouncementAnnouncement Module

Collapse

No announcement yet.

CachingConnectionFactory leaks channels in when synchronized with a transaction?Page Title Module

CachingConnectionFactory leaks channels in when synchronized with a transaction?

Sep 9th, 2011, 11:58 AM

Hello everyone,

I am switching to using transacted channels for guaranteed delivery and I started observing some weird behavior in my connections channels.

After several publishes, the broker is running out of memory because it seems that channels, when channelTransacted=true AND when on a thread with an ACTIVE transaction that the PlatformTransactionManager knows about (e.g. when the RabbitResourceHolder is synchronized with the current DB transaction).

I've stepped through the code, and realize that the channel.commit() and channel.close() operations are being deferred until after the transaction manager has committed the transaction. This is a good thing.

calls releaseResources... and the resourceHolder is still marked as synchronized with the transaction. So this method is a NOP, and the channel stays unclosed. Subsequent publishes therefore do not see existing channels in the CachingConnectionFactory, and every transacted publish within the scope of an existing transaction will result in a new channel until the broker runs out of memory.

Am I missing some configuration somewhere?

My workaround (which is not acceptable for guaranteed delivery) is to use channelTransacted = false

This looks like it might be a good catch. I don't think it should matter if you are using an async consumer (MessageListenerContainer) because the Channel is not supposed to be released in that case anyway - so your use case is synchronous? You could raise a JIRA and we can look at it for 1.0.1, or you could submit a pull request. Another workaround is to not use a transaction manager - I don't know enough about your use case to know if that would work for you.

Comment

Thanks for the quick reply.
My use case is actually on the publishing side, so yes, its "synchronous". (MessageListenerContainer doesn't apply and yes I am *not* seeing any channel "leaks" on the consuming side. Only the publishing side.) I'll look into raising a JIRA shortly and possibly a pull request if I can scrounge some time.

Oh, and I *do* need the Transaction Manager... reason being, if the publish to rabbit fails, I want to rollback the database transaction (I'm recording whether or not a given entity has been published to rabbit).