SpringSource/spring-amqp — pull request #67 by garyrussell (2012-08-16 12:33:52+00:00)
Title: AMQP-260 Bind Channel With Local Transaction

Please cherry-pick to 1.1.x

When using local transactions (no tx manager), the channel
should be bound to the thread to enable any upstream
RabbitTemplate operations to use the same channel.

When an external tx manager is a RabbitTransactionManager,
a different channel was bound, and the consumer channel
was not committed.

1. When invoking a MessageListener (not ChannelAware),
and exposeListenerChannel is true (default),
bind the consumer's channel to the thread to make
it available for up-stack RabbitTemplate operations.

2. When invoking a ChannelAwareMessageListener, and there
is no external tx manager, and exposeListenerChannel is
true (default), bind the channel to the thread to make
it available for up-stack RabbitTemplate operations.

3. When invoking a ChannelAwareMessageListener, and there
is no external tx manager, and exposeListenerChannel is
false, bind the new (temporary) channel to the thread to
make it available for up-stack RabbitTemplate operations.
Note that work on this temporary channel is committed on
the return and txSize has no bearing.

4. Whenever there is an external transaction manager, the
exposeListenerChannel is ignored - it is always exposed in
that case this is already documented in javadoc - add a
WARN log to the initialization code.

5. When there is an external transaction manager, (but not
a RabbitTransactionManager) the
listener's channel is always bound to the thread. This was
always the case and is mentioned here for completeness.

6. Previously, when an external transaction manager was
a RabbitTransactionManager, the wrong channel was bound
to the thread, and it was that channel that was committed,
instead of the listener channel. This was the originally
reported issue, with the workaround being to remove
the transaction manager; but that caused no channel to
be bound.

This last problem was due to the fact that the transaction
template obtained a new connection and bound it. It was
that connection that the TxManager committed.

Solution was to add a ThreadLocal to ConnectionFactoryUtils
to hold consumer channels. When the transaction starts,
the utils now look at this ThreadLocal before creating
a new connection.

The connection is unregistered when the consumer exits.

Add tests for transacted (with/without txMgr) for MessageListener
and ChannelAwareMessageListener to ensure the channel
is bound for use by up-stack templates.

Add test with Rabbit TxMgr showing correct channel
is bound and committed.

AMQP-260 Polishing