Auto-detect JMS sessionTransacted flag
If a JtaTransactionManager is present, it is associated with the auto-created JmsListenerContainerFactory. However, if no such transaction manager is present, local transaction support is not enabled. This gives a default situation where the message is acknowledged even before the listener is invoked. We now make sure to turn on local JMS transactions if no JtaTransactionManager is present. Fixes gh-3393
This commit is contained in:
parent
f4c95eafc2
commit
441049cf4e
|
|
@ -61,6 +61,9 @@ class JmsAnnotationDrivenConfiguration {
|
|||
if (this.transactionManager != null) {
|
||||
factory.setTransactionManager(this.transactionManager);
|
||||
}
|
||||
else {
|
||||
factory.setSessionTransacted(true);
|
||||
}
|
||||
if (this.destinationResolver != null) {
|
||||
factory.setDestinationResolver(this.destinationResolver);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,12 +23,14 @@ import org.apache.activemq.pool.PooledConnectionFactory;
|
|||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration;
|
||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.jms.annotation.EnableJms;
|
||||
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
|
||||
import org.springframework.jms.config.JmsListenerConfigUtils;
|
||||
|
|
@ -38,10 +40,13 @@ import org.springframework.jms.config.SimpleJmsListenerContainerFactory;
|
|||
import org.springframework.jms.core.JmsMessagingTemplate;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
import org.springframework.jms.listener.DefaultMessageListenerContainer;
|
||||
import org.springframework.transaction.jta.JtaTransactionManager;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
|
|
@ -137,6 +142,48 @@ public class JmsAutoConfigurationTests {
|
|||
jmsListenerContainerFactory.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultContainerFactoryWithJtaTransactionManager() {
|
||||
this.context = createContext(TestConfiguration7.class,
|
||||
EnableJmsConfiguration.class);
|
||||
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context
|
||||
.getBean("jmsListenerContainerFactory", JmsListenerContainerFactory.class);
|
||||
assertEquals(DefaultJmsListenerContainerFactory.class,
|
||||
jmsListenerContainerFactory.getClass());
|
||||
DefaultMessageListenerContainer listenerContainer = ((DefaultJmsListenerContainerFactory)
|
||||
jmsListenerContainerFactory).createListenerContainer(mock(JmsListenerEndpoint.class));
|
||||
assertFalse("wrong session transacted flag with JTA transactions", listenerContainer.isSessionTransacted());
|
||||
assertSame(this.context.getBean(JtaTransactionManager.class),
|
||||
new DirectFieldAccessor(listenerContainer).getPropertyValue("transactionManager"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultContainerFactoryNonJtaTransactionManager() {
|
||||
this.context = createContext(TestConfiguration8.class,
|
||||
EnableJmsConfiguration.class);
|
||||
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context
|
||||
.getBean("jmsListenerContainerFactory", JmsListenerContainerFactory.class);
|
||||
assertEquals(DefaultJmsListenerContainerFactory.class,
|
||||
jmsListenerContainerFactory.getClass());
|
||||
DefaultMessageListenerContainer listenerContainer = ((DefaultJmsListenerContainerFactory)
|
||||
jmsListenerContainerFactory).createListenerContainer(mock(JmsListenerEndpoint.class));
|
||||
assertTrue("wrong session transacted flag with no tx manager", listenerContainer.isSessionTransacted());
|
||||
assertNull(new DirectFieldAccessor(listenerContainer).getPropertyValue("transactionManager"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultContainerFactoryNoTransactionManager() {
|
||||
this.context = createContext(EnableJmsConfiguration.class);
|
||||
JmsListenerContainerFactory<?> jmsListenerContainerFactory = this.context
|
||||
.getBean("jmsListenerContainerFactory", JmsListenerContainerFactory.class);
|
||||
assertEquals(DefaultJmsListenerContainerFactory.class,
|
||||
jmsListenerContainerFactory.getClass());
|
||||
DefaultMessageListenerContainer listenerContainer = ((DefaultJmsListenerContainerFactory)
|
||||
jmsListenerContainerFactory).createListenerContainer(mock(JmsListenerEndpoint.class));
|
||||
assertTrue("wrong session transacted flag with no tx manager", listenerContainer.isSessionTransacted());
|
||||
assertNull(new DirectFieldAccessor(listenerContainer).getPropertyValue("transactionManager"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPubSubDisabledByDefault() {
|
||||
load(TestConfiguration.class);
|
||||
|
|
@ -350,6 +397,26 @@ public class JmsAutoConfigurationTests {
|
|||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TestConfiguration7 {
|
||||
|
||||
@Bean
|
||||
JtaTransactionManager transactionManager() {
|
||||
return mock(JtaTransactionManager.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TestConfiguration8 {
|
||||
|
||||
@Bean
|
||||
DataSourceTransactionManager transactionManager() {
|
||||
return mock(DataSourceTransactionManager.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableJms
|
||||
protected static class EnableJmsConfiguration {
|
||||
|
|
|
|||
Loading…
Reference in New Issue