Пример #1
0
        public static RabbitResourceHolder BindResourceToTransaction(RabbitResourceHolder resourceHolder, IConnectionFactory connectionFactory, bool synched)
        {
            if (TransactionSynchronizationManager.HasResource(connectionFactory) || !TransactionSynchronizationManager.IsActualTransactionActive() || !synched)
            {
                return((RabbitResourceHolder)TransactionSynchronizationManager.GetResource(connectionFactory)); // NOSONAR never null
            }

            TransactionSynchronizationManager.BindResource(connectionFactory, resourceHolder);
            resourceHolder.SynchronizedWithTransaction = true;
            if (TransactionSynchronizationManager.IsSynchronizationActive())
            {
                TransactionSynchronizationManager.RegisterSynchronization(new RabbitResourceSynchronization(resourceHolder, connectionFactory));
            }

            return(resourceHolder);
        }
Пример #2
0
        protected virtual void DoInvokeListener(IChannelAwareMessageListener listener, R.IModel channel, object data)
        {
            Message message = null;
            RabbitResourceHolder resourceHolder = null;
            var channelToUse = channel;
            var boundHere    = false;

            try
            {
                if (!ExposeListenerChannel)
                {
                    // 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.SynchronizedWithTransaction = true;
                        TransactionSynchronizationManager.BindResource(ConnectionFactory, resourceHolder);
                        boundHere = true;
                    }
                }
                else
                {
                    // if locally transacted, bind the current channel to make it available to RabbitTemplate
                    if (IsChannelLocallyTransacted)
                    {
                        var localResourceHolder = new RabbitResourceHolder(channelToUse, false);
                        localResourceHolder.SynchronizedWithTransaction = true;
                        TransactionSynchronizationManager.BindResource(ConnectionFactory, localResourceHolder);
                        boundHere = true;
                    }
                }

                // Actually invoke the message listener...
                try
                {
                    if (data is List <Message> asList)
                    {
                        listener.OnMessageBatch(asList, channelToUse);
                    }
                    else
                    {
                        message = (Message)data;
                        listener.OnMessage(message, channelToUse);
                    }
                }
                catch (Exception e)
                {
                    _logger?.LogError("Exception in OnMessage call", e);
                    throw WrapToListenerExecutionFailedExceptionIfNeeded(e, data);
                }
            }
            finally
            {
                CleanUpAfterInvoke(resourceHolder, channelToUse, boundHere);
            }
        }