예제 #1
0
        protected override void DoBegin(object transaction, ITransactionDefinition definition)
        {
            if (definition.IsolationLevel != AbstractTransactionDefinition.ISOLATION_DEFAULT)
            {
                throw new InvalidIsolationLevelException("AMQP does not support an isolation level concept");
            }

            var txObject = (RabbitTransactionObject)transaction;
            RabbitResourceHolder resourceHolder = null;

            try
            {
                resourceHolder = ConnectionFactoryUtils.GetTransactionalResourceHolder(ConnectionFactory, true);
                _logger?.LogDebug("Created AMQP transaction on channel [" + resourceHolder.GetChannel() + "]");

                txObject.ResourceHolder = resourceHolder;
                txObject.ResourceHolder.SynchronizedWithTransaction = true;
                var timeout = DetermineTimeout(definition);
                if (timeout != AbstractTransactionDefinition.TIMEOUT_DEFAULT)
                {
                    txObject.ResourceHolder.SetTimeoutInSeconds(timeout);
                }

                TransactionSynchronizationManager.BindResource(ConnectionFactory, txObject.ResourceHolder);
            }
            catch (AmqpException ex)
            {
                if (resourceHolder != null)
                {
                    ConnectionFactoryUtils.ReleaseResources(resourceHolder);
                }

                throw new CannotCreateTransactionException("Could not create AMQP transaction", ex);
            }
        }
예제 #2
0
        public void Start()
        {
            Logger?.LogDebug("Starting consumer {consumer}", ToString());
            try
            {
                ResourceHolder = ConnectionFactoryUtils.GetTransactionalResourceHolder(ConnectionFactory, Transactional);
                Channel        = ResourceHolder.GetChannel();

                // ClosingRecoveryListener.AddRecoveryListenerIfNecessary(Channel);
            }
            catch (RabbitAuthenticationException e)
            {
                throw new FatalListenerStartupException("Authentication failure", e);
            }

            DeliveryTags.Clear();
            ActiveObjectCounter.Add(this);
            PassiveDeclarations();
            SetQosAndCreateConsumers();
        }
        public void TestReceiveBlockingGlobalTx()
        {
            template.ConvertAndSend(ROUTE, "blockGTXNoTO");
            var resourceHolder = ConnectionFactoryUtils
                                 .GetTransactionalResourceHolder(template.ConnectionFactory, true);

            TransactionSynchronizationManager.SetActualTransactionActive(true);
            ConnectionFactoryUtils.BindResourceToTransaction(resourceHolder, template.ConnectionFactory, true);
            template.ReceiveTimeout      = -1;
            template.IsChannelTransacted = true;
            var o = template.ReceiveAndConvert <string>(ROUTE);

            resourceHolder.CommitAll();
            resourceHolder.CloseAll();
            Assert.Same(resourceHolder, TransactionSynchronizationManager.UnbindResource(template.ConnectionFactory));
            Assert.NotNull(o);
            Assert.Equal("blockGTXNoTO", o);
            template.ReceiveTimeout = 0;
            Assert.Null(template.Receive(ROUTE));
        }
예제 #4
0
        /// <summary>Do begin.</summary>
        /// <param name="transaction">The transaction.</param>
        /// <param name="definition">The definition.</param>
        protected override void DoBegin(object transaction, ITransactionDefinition definition)
        {
            // https://jira.springsource.org/browse/SPRNET-1444 (SPRNET 2.0) has default TransactionIsolationLevel as IsolationLevel.Unspecified, letting this work. Will not work for SPRNET <= 1.3.2.
            if (definition.TransactionIsolationLevel != IsolationLevel.Unspecified)
            {
                throw new InvalidIsolationLevelException("AMQP does not support an isolation level concept");
            }

            var transactionObject = (RabbitTransactionObject)transaction;
            RabbitResourceHolder resourceHolder = null;

            try
            {
                resourceHolder = ConnectionFactoryUtils.GetTransactionalResourceHolder(this.ConnectionFactory, true);
                Logger.Debug(m => m("Created AMQP transaction on channel [{0}]", resourceHolder.Channel));

                // resourceHolder.DeclareTransactional();
                transactionObject.ResourceHolder = resourceHolder;
                transactionObject.ResourceHolder.SynchronizedWithTransaction = true;
                var timeout = this.DetermineTimeout(definition);
                if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
                {
                    transactionObject.ResourceHolder.TimeoutInSeconds = timeout;
                }

                TransactionSynchronizationManager.BindResource(this.ConnectionFactory, transactionObject.ResourceHolder);
            }
            catch (AmqpException ex)
            {
                if (resourceHolder != null)
                {
                    ConnectionFactoryUtils.ReleaseResources(resourceHolder);
                }

                throw new CannotCreateTransactionException("Could not create AMQP transaction", ex);
            }
        }
        /// <summary>The start.</summary>
        public void Start()
        {
            Logger.Debug(m => m("Starting consumer {0}", this));

            this.channel  = ConnectionFactoryUtils.GetTransactionalResourceHolder(this.connectionFactory, this.transactional).Channel;
            this.consumer = new InternalConsumer(this.channel, this);
            this.deliveryTags.Clear();
            this.activeObjectCounter.Add(this);
            var passiveDeclareTries = 3; // mirrored queue might be being moved

            while (passiveDeclareTries > 0)
            {
                passiveDeclareTries--;
                try
                {
                    if (!this.acknowledgeMode.IsAutoAck())
                    {
                        // Set basicQos before calling basicConsume (otherwise if we are not acking the broker
                        // will send blocks of 100 messages)
                        // The Java client includes a convenience method BasicQos(ushort prefetchCount), which sets 0 as the prefetchSize and false as global
                        this.channel.BasicQos(0, (ushort)this.prefetchCount, false);
                    }

                    foreach (var t in this.queues)
                    {
                        this.channel.QueueDeclarePassive(t);
                    }

                    passiveDeclareTries = 0;
                }
                catch (Exception e)
                {
                    if (passiveDeclareTries > 0 && this.channel.IsOpen)
                    {
                        Logger.Warn(m => m("Reconnect failed; retries left=" + (passiveDeclareTries - 1)), e);
                        try
                        {
                            Thread.Sleep(5000);
                        }
                        catch (ThreadInterruptedException e1)
                        {
                            Thread.CurrentThread.Interrupt();
                        }
                    }
                    else
                    {
                        this.activeObjectCounter.Release(this);
                        throw new FatalListenerStartupException("Cannot prepare queue for listener. Either the queue doesn't exist or the broker will not allow us to use it.", e);
                    }
                }
            }

            try
            {
                foreach (var t in this.queues)
                {
                    this.channel.BasicConsume(t, this.acknowledgeMode.IsAutoAck(), this.consumer);
                    Logger.Debug(m => m("Started on queue '{0}': {1}", t, this));
                }
            }
            catch (Exception e)
            {
                throw RabbitUtils.ConvertRabbitAccessException(e);
            }
        }
예제 #6
0
 /// <summary>
 /// Get a transactional resource holder.
 /// </summary>
 /// <returns>
 /// The rabbit resource holder.
 /// </returns>
 protected RabbitResourceHolder GetTransactionalResourceHolder()
 {
     return(ConnectionFactoryUtils.GetTransactionalResourceHolder(this.connectionFactory, this.ChannelTransacted));
 }