Why Spring DataSourceTransactionManager suppress the concurrent number of ActiveMQ consumer - spring

I got one strange problem.
when I config a DataSourceTransactionManager with spring xml, the concurrent consumers of ActiveMQ were suppressed whatever I change "maxConcurrentConsumers" property value. I have 5 queues, the total concurrent consumers of all 5 queue always kept at 8.
if I remove DataSourceTransactionManager bean, each queue's concurrent consumers reached the max number 5 declared in "maxConcurrentConsumers" .
The DataSourceTransactionManager work for dataSource, i cannot understand why it affected to ActiveMQ.
version:
Spring 3.2.5.RELEASE
ActiveMq 5.9.0
application.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- once I add this, activemq total consumers always kept at 8 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- activemq consumer connection -->
<bean id="consumerConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL">
<value>tcp://localhost:61616</value>
</property>
</bean>
</property>
<property name="maxConnections" value="5"></property>
</bean>
<!-- i have 5 queues -->
<bean id="test_1" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="test_1}" />
</bean>
<bean id="test_2" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="test_2}" />
</bean>
<bean id="test_3" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="test_3}" />
</bean>
<bean id="test_4" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="test_4}" />
</bean>
<bean id="test_5" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="test_5}" />
</bean>
<!-- consumer listener container -->
<bean id="testOneMessageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="consumerConnectionFactory"></property>
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="5" />
<property name="destination" ref="test_1"></property>
<property name="messageListener" ref="demoBusinessListener"></property>
</bean>
<bean id="testTwoMessageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="consumerConnectionFactory"></property>
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="5" />
<property name="destination" ref="test_2"></property>
<property name="messageListener" ref="demoBusinessListener"></property>
</bean>
<bean id="testThreeMessageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="consumerConnectionFactory"></property>
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="5" />
<property name="destination" ref="test_3"></property>
<property name="messageListener" ref="demoBusinessListener"></property>
</bean>
<bean id="testFourMessageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="consumerConnectionFactory"></property>
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="5" />
<property name="destination" ref="test_4"></property>
<property name="messageListener" ref="demoBusinessListener"></property>
</bean>
<bean id="testFiveMessageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="consumerConnectionFactory"></property>
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="5" />
<property name="destination" ref="test_5"></property>
<property name="messageListener" ref="demoBusinessListener"></property>
</bean>
can someone help me!!!

after some test, i found a way to resolve this problem.
when i change the dataSource "maxActive" parameter to a number greater than sum of all mq listener maxConcurrentConsumers. it work fine.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="120" />
</bean>
it seems that the max number of activemq listener thread affected by Datasource maxActive parameter

Related

Not able to ref dataSource from other bean configuartion in Spring

<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="${models.DS_POOL_NAME}" />
</property>
</bean>
<bean id="DBPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="properties">
<bean class="org.apache.commons.configuration2.ConfigurationConverter" factory-method="getProperties">
<constructor-arg>
<bean id="DatabaseConfigurator" class="org.apache.commons.configuration2.DatabaseConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="table" value="sample" />
<property name="keyColumn" value="PROPERTY" />
<property name="valueColumn" value="VALUE" />
<property name="configurationNameColumn" value="GROUP_NAME" />
<property name="configurationName" value="new" />
</bean>
</constructor-arg>
</bean>
</property>
</bean>
when we ref dataSource in DBPlaceholder bean then ${models.DS_POOL_NAME} will showing error because this value is coming from properties

JMS Message Redelivery not working for Topic in Spring + ActiveMQ + Atomikos + JTA + Tomcat

I have following configuration in the application that works perfectly fine with queues and redelivers the messages when a RuntimeException occurs with transaction rollback as expected.
But the same configuration fails to redeliver message with topics and emits following warning message:
WARN DefaultMessageListenerContainer - Setup of JMS message listener invoker failed for destination 'XXX_TOPIC' - trying to recover. Cause: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException: One or more resources refused to commit (possibly because of a timeout in the resource - see the log for details). This transaction has been rolled back instead.
Configuration:
<bean id="amqConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"/>
<!-- <property name="sendTimeout" value="1000"/> -->
<property name="redeliveryPolicy" ref="redeliveryPolicy"/>
</bean>
<!-- Atomikos Connection Factory Wrapper For Gobal Tx -->
<bean id="queueConnectionFactoryBean" class="com.atomikos.jms.AtomikosConnectionFactoryBean">
<property name="uniqueResourceName" value="amq1" />
<property name="xaConnectionFactory" ref="amqConnectionFactory" />
</bean>
<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory">
<ref bean="queueConnectionFactoryBean"/>
</property>
<property name="sessionCacheSize" value="20"/>
<property name="cacheConsumers" value="false"/>
</bean>
<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<bean class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init"
destroy-method="close">
<property name="forceShutdown" value="false" />
</bean>
</property>
<property name="userTransaction">
<bean class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
</property>
</bean>
<!-- Topic configuration -->
<bean id="messageListener1" class="com.x.y.impl.JmsMessageListener"></bean>
<bean id="container1" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="destinationName" value="XXX_TOPIC"/>
<property name="messageListener" ref="messageListener1" />
<property name="pubSubDomain" value="true" />
<property name="transactionManager" ref="jtaTransactionManager" />
<property name="concurrency" value="1" />
<property name="receiveTimeout" value="3000" />
<!-- For local session and Atomikos-->
<property name="sessionTransacted" value="true"/>
</bean>
<!-- Bean configuration -->
<bean id="messageListener2" class="com.x.y.impl.JmsMessageListener"></bean>
<bean id="container2" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="destinationName" value="XXX_QUEUE"/>
<property name="messageListener" ref="messageListener2" />
<property name="pubSubDomain" value="false" />
<property name="transactionManager" ref="jtaTransactionManager" />
<property name="concurrency" value="1" />
<!-- For local session and Atomikos-->
<property name="sessionTransacted" value="true"/>
</bean>
The Spring version used is 3.1, ActiveMQ 5.14, Atomikos 4.0.6.
Please let me know if i missed any configuration for topic DMLC.

Configure Multiple JPA Repositories in CrudRepository approach

I am trying to configure the multiple JPA repositories in my web application. Currently I have one Repository as mentioned below. I am using Crud Repository
<jpa:repositories base-package="com.mypackage1" factory-class="org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory">
<repository:include-filter type="assignable" expression="com.MyFirstRepository"/>
</jpa:repositories>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.mypackage1.Model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="database" value="H2" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:database/~test" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
If I need to configure multiple repositories,
<bean id="entityManagerFactory2"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource2" />
<property name="packagesToScan" value="com.mypackage2.Model" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="database" value="H2" />
</bean>
</property>
</bean>
<bean id="transactionManager2" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory2" />
</bean>
<bean id="dataSource2"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:database/~test2" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
I am not able to find any appropriate configuratiuon for this.
Appreciate help on this.

Camel Transaction Configuration Issue: javax.persistence.TransactionRequiredException

I'm configuring JMS Transactions in Camel 2.10.4 routes. When I run my app, a javax.persistence.TransactionRequiredException: no transaction in progress is thrown. From my research, I found out that this exception is thrown when no method is marked #Transactional. The relevant sections in my application context XML config file is shown:
<bean id="txMgr" class="org.springframework.jms.connection.JmsTransactionManager">
<property name="connectionFactory" ref="pooledConnectionFactory" />
</bean>
<bean id="REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txMgr" />
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" />
</bean>
<bean id="pooledConnectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="maxConnections" value="8" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="jmsConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="configuration" ref="jmsConfig" />
</bean>
<bean id="jmsConfig"
class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledConnectionFactory"/>
<property name="transacted" value="true" />
<property name="transactionManager" ref="txMgr" />
<property name="concurrentConsumers" value="3"/>
</bean>
Besides the JMS-specific configuration, I also have JPA configuration, which is shown below:
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<bean class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</property>
</bean>
<bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="fileRecord" />
</bean>
If I disable transactions, the configuration works. When I enable it, however, all the other steps succeeds except the bit where the data is to be inserted into the database (at the JPA endpoint).
Any suggestions on what I need to change or add will be appreciated very much.

EhCache CacheManager with multiple EntityManagerFactory

And one entityManagerFactory in spring-server.xml.
But i must generate one more entityManager, and i do it with
Persistence.createEntityManagerFactory("myotherpersistenceunitname");
but i get exception
Caused by: net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.
The source of the existing CacheManager is: DefaultConfigurationSource [ ehcache.xml or ehcache-failsafe.xml ]
at net.sf.ehcache.CacheManager.assertNoCacheManagerExistsWithSameName(CacheManager.java:457)
at net.sf.ehcache.CacheManager.init(CacheManager.java:354)
at net.sf.ehcache.CacheManager.<init>(CacheManager.java:242)
at net.sf.ehcache.hibernate.EhCacheRegionFactory.start(EhCacheRegionFactory.java:70)
spring.xml:
<context:property-placeholder location="classpath:application.properties"/>
<context:component-scan base-package="merve.web.app" >
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" />
</context:component-scan>
<context:annotation-config/>
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
<cache:annotation-driven />
<bean id="properties" class="merve.web.app.configuration.PropertyResourceConfiguration" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myPU"/>
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${database.target}"/>
<property name="showSql" value="${database.showSql}" />
</bean>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${database.driver}"/>
<property name="jdbcUrl" value="${database.url}"/>
<property name="user" value="${database.username}"/>
<property name="password" value="${database.password}"/>
<property name="minPoolSize" value="2"/>
<property name="maxPoolSize" value="10"/>
<property name="breakAfterAcquireFailure" value="false"/>
<property name="acquireRetryAttempts" value="3"/>
<property name="idleConnectionTestPeriod" value="300" />
<property name="testConnectionOnCheckout" value="true" />
</bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="jamesEntityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="jamesPU"/>
<property name="dataSource" ref="dataSourceJames" />
<property name="persistenceXmlLocation" value="classpath:META-INF/james-persistence.xml"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<bean id="dataSourceJames" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="jdbcUrl" value="jdbc:derby:../var/store/derby;create=true"/>
<property name="user" value="app"/>
<property name="password" value="app"/>
<property name="minPoolSize" value="2"/>
<property name="maxPoolSize" value="10"/>
<property name="breakAfterAcquireFailure" value="false"/>
<property name="acquireRetryAttempts" value="3"/>
<property name="idleConnectionTestPeriod" value="300" />
<property name="testConnectionOnCheckout" value="true" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
<!-- Ehcache library setup -->
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:shared="true" p:config-location="classpath:ehcache.xml"/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" >
<property name="cacheManager"><ref local="ehcache"></ref></property>
</bean>
<dwr:configuration/>
<dwr:annotation-scan base-package="tuxi.web.app.service.dwr" scanRemoteProxy="true" scanDataTransferObject="true"/>
<dwr:url-mapping />
<dwr:controller id="dwrController"/>
</beans>
The problem, described here, and fixed in the source is not using the EhCache singleton correctly. The answer depends on which version of spring-context-support AND which version of EhCache you are using. For both, you need to be using EhCache 2.6 or greater:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.6.0</version>
</dependency>
Next, determine what to do based on your spring-context-support version:
If using Spring 3.1/3.2
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:shared="true"
p:config-location="classpath:ehcache.xml"/>
If using Spring 4.x
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:shared="false"
P:acceptExisting="true"
p:config-location="classpath:ehcache.xml"/>
Try naming both cacheManagers differently in ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="ehCacheManager1">
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="ehCacheManager2">

Resources