Example usage for org.springframework.amqp.rabbit.connection RabbitUtils commitIfNecessary

List of usage examples for org.springframework.amqp.rabbit.connection RabbitUtils commitIfNecessary

Introduction

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

Prototype

public static void commitIfNecessary(Channel channel) 

Source Link

Document

Commit the Channel if not within a JTA transaction.

Usage

From source file:org.kurento.rabbitmq.RabbitTemplate.java

/**
 * Send the given message to the specified exchange.
 *
 * @param channel//from w  w w  .  j  av  a  2s.co  m
 *            The RabbitMQ Channel to operate within.
 * @param exchange
 *            The name of the RabbitMQ exchange to send to.
 * @param routingKey
 *            The routing key.
 * @param message
 *            The Message to send.
 * @param correlationData
 *            The correlation data.
 * @throws IOException
 *             If thrown by RabbitMQ API methods
 */
protected void doSend(Channel channel, String exchange, String routingKey, Message message,
        CorrelationData correlationData) throws Exception {
    if (logger.isDebugEnabled()) {
        logger.debug("Publishing message on exchange [" + exchange + "], routingKey = [" + routingKey + "]");
    }

    if (exchange == null) {
        // try to send to configured exchange
        exchange = this.exchange;
    }

    if (routingKey == null) {
        // try to send to configured routing key
        routingKey = this.routingKey;
    }
    if (this.confirmCallback != null && channel instanceof PublisherCallbackChannel) {
        PublisherCallbackChannel publisherCallbackChannel = (PublisherCallbackChannel) channel;
        publisherCallbackChannel.addPendingConfirm(this, channel.getNextPublishSeqNo(),
                new PendingConfirm(correlationData, System.currentTimeMillis()));
    }
    boolean mandatory = this.returnCallback != null && this.mandatory;
    MessageProperties messageProperties = message.getMessageProperties();
    if (mandatory) {
        messageProperties.getHeaders().put(PublisherCallbackChannel.RETURN_CORRELATION, this.uuid);
    }
    BasicProperties convertedMessageProperties = this.messagePropertiesConverter
            .fromMessageProperties(messageProperties, encoding);
    channel.basicPublish(exchange, routingKey, mandatory, convertedMessageProperties, message.getBody());
    // Check if commit needed
    if (isChannelLocallyTransacted(channel)) {
        // Transacted channel created by this template -> commit.
        RabbitUtils.commitIfNecessary(channel);
    }
}

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

public void rollbackAll() {
    for (Channel channel : this.channels) {
        if (logger.isDebugEnabled()) {
            logger.debug("Rolling back messages to channel: " + channel);
        }//from w  w w .ja  v  a2  s.c o  m
        RabbitUtils.rollbackIfNecessary(channel);
        if (deliveryTags.containsKey(channel)) {
            for (Long deliveryTag : deliveryTags.get(channel)) {
                try {
                    channel.basicReject(deliveryTag, true);
                } catch (IOException ex) {
                    throw new AmqpIOException(ex);
                }
            }
            // Need to commit the reject (=nack)
            RabbitUtils.commitIfNecessary(channel);
        }
    }
}

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 w ww  .  ja  va2 s. com
 * 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);
            }
        }
    }
}

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

/**
 * Perform a rollback, handling rollback exceptions properly.
 * //from w w  w. jav a2s. co m
 * @param ex
 *            the thrown application exception or error
 * @throws Exception
 *             in case of a rollback error
 */
public void rollbackOnExceptionIfNecessary(Throwable ex) throws Exception {

    boolean ackRequired = !acknowledgeMode.isAutoAck() && !acknowledgeMode.isManual();
    try {
        if (transactional) {
            if (logger.isDebugEnabled()) {
                logger.debug("Initiating transaction rollback on application exception: " + ex);
            }
            RabbitUtils.rollbackIfNecessary(channel);
        }
        if (ackRequired) {
            if (logger.isDebugEnabled()) {
                logger.debug("Rejecting messages");
            }
            boolean shouldRequeue = this.defaultRequeuRejected;
            Throwable t = ex;
            while (shouldRequeue && t != null) {
                if (t instanceof AmqpRejectAndDontRequeueException) {
                    shouldRequeue = false;
                }
                t = t.getCause();
            }
            for (Long deliveryTag : deliveryTags) {
                // With newer RabbitMQ brokers could use basicNack here...
                channel.basicReject(deliveryTag, shouldRequeue);
            }
            if (transactional) {
                // Need to commit the reject (=nack)
                RabbitUtils.commitIfNecessary(channel);
            }
        }
    } catch (Exception e) {
        logger.error("Application exception overridden by rollback exception", ex);
        throw e;
    } finally {
        deliveryTags.clear();
        retryDeliveryTags.clear();
    }
}

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

/**
 * Perform a commit or message acknowledgement, as appropriate.
 * /*from   w w w .j  a v a2s .c  om*/
 * @param locallyTransacted
 * @throws IOException
 */
public boolean commitIfNecessary(boolean locallyTransacted) throws IOException {

    if (deliveryTags.isEmpty()) {
        return false;
    }

    try {

        boolean ackRequired = !acknowledgeMode.isAutoAck() && !acknowledgeMode.isManual();

        if (ackRequired) {

            if (transactional && !locallyTransacted) {

                // Not locally transacted but it is transacted so it
                // could be synchronized with an external transaction
                for (Long deliveryTag : deliveryTags) {
                    ConnectionFactoryUtils.registerDeliveryTag(connectionFactory, channel, deliveryTag);
                }

            } else {

                if (!deliveryTags.isEmpty()) {
                    long deliveryTag = new ArrayList<Long>(deliveryTags).get(deliveryTags.size() - 1);
                    channel.basicAck(deliveryTag, true);
                }

            }
        }

        if (locallyTransacted) {
            // For manual acks we still need to commit
            RabbitUtils.commitIfNecessary(channel);
        }

    } finally {
        deliveryTags.clear();
        retryDeliveryTags.clear();
    }

    return true;

}