public bool CommitIfNecessary(bool localTx)
        {
            if (DeliveryTags.Count == 0)
            {
                return(false);
            }

            var isLocallyTransacted = localTx || (Transactional && TransactionSynchronizationManager.GetResource(ConnectionFactory) == null);

            try
            {
                var ackRequired = !AcknowledgeMode.IsAutoAck() && !AcknowledgeMode.IsManual();
                if (ackRequired && (!Transactional || isLocallyTransacted))
                {
                    var deliveryTag = new List <ulong>(DeliveryTags)[DeliveryTags.Count - 1];
                    Channel.BasicAck(deliveryTag, true);
                }

                if (isLocallyTransacted)
                {
                    // For manual acks we still need to commit
                    RabbitUtils.CommitIfNecessary(Channel);
                }
            }
            finally
            {
                DeliveryTags.Clear();
            }

            return(true);
        }
Exemple #2
0
        protected virtual void ValidateConfiguration()
        {
            if (!(ExposeListenerChannel || !AcknowledgeMode.IsManual()))
            {
                throw new ArgumentException(
                          "You cannot acknowledge messages manually if the channel is not exposed to the listener "
                          + "(please check your configuration and set exposeListenerChannel=true or " +
                          "acknowledgeMode!=MANUAL)");
            }

            if (IsChannelTransacted && AcknowledgeMode.IsAutoAck())
            {
                throw new ArgumentException(
                          "The acknowledgeMode is NONE (autoack in Rabbit terms) which is not consistent with having a "
                          + "transactional channel. Either use a different AcknowledgeMode or make sure " +
                          "channelTransacted=false");
            }
        }
        public void RollbackOnExceptionIfNecessary(Exception ex)
        {
            bool ackRequired = !AcknowledgeMode.IsAutoAck() && (!AcknowledgeMode.IsManual() || ContainerUtils.IsRejectManual(ex));

            try
            {
                if (Transactional)
                {
                    Logger?.LogDebug(ex, "Initiating transaction rollback on application exception");
                    RabbitUtils.RollbackIfNecessary(Channel);
                }

                if (ackRequired)
                {
                    if (DeliveryTags.Count > 0)
                    {
                        ulong deliveryTag = DeliveryTags.Max();
                        Channel.BasicNack(deliveryTag, true, ContainerUtils.ShouldRequeue(DefaultRequeueRejected, ex, Logger));
                    }

                    if (Transactional)
                    {
                        // Need to commit the reject (=nack)
                        RabbitUtils.CommitIfNecessary(Channel);
                    }
                }
            }
            catch (Exception e)
            {
                Logger?.LogError(ex, "Application exception overridden by rollback exception");
                throw RabbitExceptionTranslator.ConvertRabbitAccessException(e); // NOSONAR stack trace loss
            }
            finally
            {
                DeliveryTags.Clear();
            }
        }