List of usage examples for org.springframework.amqp.rabbit.connection RabbitResourceHolder setSynchronizedWithTransaction
public void setSynchronizedWithTransaction(boolean synchronizedWithTransaction)
From source file:org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.java
public static void bindResourceToTransaction(RabbitResourceHolder resourceHolder, ConnectionFactory connectionFactory, boolean synched) { if (TransactionSynchronizationManager.hasResource(connectionFactory) || !TransactionSynchronizationManager.isActualTransactionActive() || !synched) { return;/*from w w w .j a v a 2 s . c o m*/ } TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolder); resourceHolder.setSynchronizedWithTransaction(true); if (TransactionSynchronizationManager.isSynchronizationActive()) { TransactionSynchronizationManager.registerSynchronization( new RabbitResourceSynchronization(resourceHolder, connectionFactory, synched)); } }
From source file:org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.java
/** * Invoke the specified listener: either as standard MessageListener or (preferably) as SessionAwareMessageListener. * @param channel the Rabbit Channel to operate on * @param message the received Rabbit Message * @throws Exception if thrown by Rabbit API methods * @see #setMessageListener// www . jav a 2 s .c o m */ protected void actualInvokeListener(Channel channel, Message message) throws Exception { Object listener = getMessageListener(); if (listener instanceof ChannelAwareMessageListener) { doInvokeListener((ChannelAwareMessageListener) listener, channel, message); } else if (listener instanceof MessageListener) { boolean bindChannel = isExposeListenerChannel() && isChannelLocallyTransacted(); if (bindChannel) { RabbitResourceHolder resourceHolder = new RabbitResourceHolder(channel, false); resourceHolder.setSynchronizedWithTransaction(true); TransactionSynchronizationManager.bindResource(this.getConnectionFactory(), resourceHolder); } try { doInvokeListener((MessageListener) listener, message); } finally { if (bindChannel) { // unbind if we bound TransactionSynchronizationManager.unbindResource(this.getConnectionFactory()); } } } else if (listener != null) { throw new FatalListenerExecutionException( "Only MessageListener and SessionAwareMessageListener supported: " + listener); } else { throw new FatalListenerExecutionException( "No message listener specified - see property 'messageListener'"); } }
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 www.jav a 2 s . c om*/ * 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); } } } }