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); }
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); } }