Example usage for org.springframework.amqp.rabbit.connection RabbitResourceHolder setSynchronizedWithTransaction

List of usage examples for org.springframework.amqp.rabbit.connection RabbitResourceHolder setSynchronizedWithTransaction

Introduction

In this page you can find the example usage for org.springframework.amqp.rabbit.connection RabbitResourceHolder setSynchronizedWithTransaction.

Prototype

public void setSynchronizedWithTransaction(boolean synchronizedWithTransaction) 

Source Link

Document

Mark the resource as synchronized with a transaction.

Usage

From source file:org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.java

public static void bindResourceToTransaction(RabbitResourceHolder resourceHolder,
        ConnectionFactory connectionFactory, boolean synched) {
    if (TransactionSynchronizationManager.hasResource(connectionFactory)
            || !TransactionSynchronizationManager.isActualTransactionActive() || !synched) {
        return;/*from w w w .j a v  a  2 s . c o  m*/
    }
    TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolder);
    resourceHolder.setSynchronizedWithTransaction(true);
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        TransactionSynchronizationManager.registerSynchronization(
                new RabbitResourceSynchronization(resourceHolder, connectionFactory, synched));
    }
}

From source file:org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.java

/**
 * Invoke the specified listener: either as standard MessageListener or (preferably) as SessionAwareMessageListener.
 * @param channel the Rabbit Channel to operate on
 * @param message the received Rabbit Message
 * @throws Exception if thrown by Rabbit API methods
 * @see #setMessageListener//  www . jav a  2  s .c  o m
 */
protected void actualInvokeListener(Channel channel, Message message) throws Exception {
    Object listener = getMessageListener();
    if (listener instanceof ChannelAwareMessageListener) {
        doInvokeListener((ChannelAwareMessageListener) listener, channel, message);
    } else if (listener instanceof MessageListener) {
        boolean bindChannel = isExposeListenerChannel() && isChannelLocallyTransacted();
        if (bindChannel) {
            RabbitResourceHolder resourceHolder = new RabbitResourceHolder(channel, false);
            resourceHolder.setSynchronizedWithTransaction(true);
            TransactionSynchronizationManager.bindResource(this.getConnectionFactory(), resourceHolder);
        }
        try {
            doInvokeListener((MessageListener) listener, message);
        } finally {
            if (bindChannel) {
                // unbind if we bound
                TransactionSynchronizationManager.unbindResource(this.getConnectionFactory());
            }
        }
    } else if (listener != null) {
        throw new FatalListenerExecutionException(
                "Only MessageListener and SessionAwareMessageListener supported: " + listener);
    } else {
        throw new FatalListenerExecutionException(
                "No message listener specified - see property 'messageListener'");
    }
}

From source file:org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.java

/**
 * Invoke the specified listener as Spring ChannelAwareMessageListener, exposing a new Rabbit Session (potentially
 * with its own transaction) to the listener if demanded.
 * @param listener the Spring ChannelAwareMessageListener to invoke
 * @param channel the Rabbit Channel to operate on
 * @param message the received Rabbit Message
 * @throws Exception if thrown by Rabbit API methods or listener itself.
 * <p>/*from www.jav  a 2  s  .  c om*/
 * Exception thrown from listener will be wrapped to {@link ListenerExecutionFailedException}.
 * @see ChannelAwareMessageListener
 * @see #setExposeListenerChannel(boolean)
 */
protected void doInvokeListener(ChannelAwareMessageListener listener, Channel channel, Message message)
        throws Exception {

    RabbitResourceHolder resourceHolder = null;
    Channel channelToUse = channel;
    boolean boundHere = false;
    try {
        if (!isExposeListenerChannel()) {
            // We need to expose a separate Channel.
            resourceHolder = getTransactionalResourceHolder();
            channelToUse = resourceHolder.getChannel();
            /*
             * If there is a real transaction, the resource will have been bound; otherwise
             * we need to bind it temporarily here. Any work done on this channel
             * will be committed in the finally block.
             */
            if (isChannelLocallyTransacted()
                    && !TransactionSynchronizationManager.isActualTransactionActive()) {
                resourceHolder.setSynchronizedWithTransaction(true);
                TransactionSynchronizationManager.bindResource(this.getConnectionFactory(), resourceHolder);
                boundHere = true;
            }
        } else {
            // if locally transacted, bind the current channel to make it available to RabbitTemplate
            if (isChannelLocallyTransacted()) {
                RabbitResourceHolder localResourceHolder = new RabbitResourceHolder(channelToUse, false);
                localResourceHolder.setSynchronizedWithTransaction(true);
                TransactionSynchronizationManager.bindResource(this.getConnectionFactory(),
                        localResourceHolder);
                boundHere = true;
            }
        }
        // Actually invoke the message listener...
        try {
            listener.onMessage(message, channelToUse);
        } catch (Exception e) {
            throw wrapToListenerExecutionFailedExceptionIfNeeded(e, message);
        }
    } finally {
        if (resourceHolder != null && boundHere) {
            // so the channel exposed (because exposeListenerChannel is false) will be closed
            resourceHolder.setSynchronizedWithTransaction(false);
        }
        ConnectionFactoryUtils.releaseResources(resourceHolder);
        if (boundHere) {
            // unbind if we bound
            TransactionSynchronizationManager.unbindResource(this.getConnectionFactory());
            if (!isExposeListenerChannel() && isChannelLocallyTransacted()) {
                /*
                 *  commit the temporary channel we exposed; the consumer's channel
                 *  will be committed later. Note that when exposing a different channel
                 *  when there's no transaction manager, the exposed channel is committed
                 *  on each message, and not based on txSize.
                 */
                RabbitUtils.commitIfNecessary(channelToUse);
            }
        }
    }
}