Spring service going down after DB connection down - spring

I have a spring cxf web service application deployed into a JBOSS server. The service is working fine and once in a while(within 5-6 days after the server start) , I get and error"Could not open JDBC Connection for transaction; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object" and that particular service goes down
I have around 17 services inside this application and only the service which had this DB connection issue goes down till I restart the server.
Other services are up.
Below is my JDBC template configuration.
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="10" />
<property name="maxIdle" value="10" />
<property name="maxActive" value="100" />
<property name="maxWait" value="1000" />
<property name="validationQuery" value="select 1 from sysibm.sysdummy1" />
<property name="testOnBorrow" value="true" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="1200000" />
<property name="minEvictableIdleTimeMillis" value="1800000" />
<property name="numTestsPerEvictionRun" value="5" />
<property name="defaultAutoCommit" value="false" />
</bean>
Your help is greately appreciated.

I'd recommend that you switch to a JNDI data source managed by JBOSS.

It sounds like either a connection leak or that you have some really long-running processes that hold a database connection long-term, eventually exhausting your connection pool. It's also possible, though unlikely, that you have very high database latency, that a dead connection shows up in the pool, and that recognizing the dead connection, establishing a new one, and validating it takes longer than the 1 second you've given the pool.

You can try and change the datasource to the :
org.springframework.jdbc.datasource.DriverManagerDataSource
It's better to configure a data source with JBoss and do a Java EE-jndi lookup.
http://techdive.in/spring/spring-jndi-datasource-configuration-jboss

Related

Activemq consumer can not reconnect automatically

jms.brokerurl=failover:(tcp://ip:61616?wireFormat.maxInactivityDuration=0)?jms.prefetchPolicy.queuePrefetch\=2&randomize\=false&initialReconnectDelay\=50&timeout\=3000
Spring configuration
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="maxConnections" value="10"/>
<property name="maximumActive" value="10"/>
<property name="idleTimeout" value="0"/>
</bean>
<bean id="receiveContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="pooledConnectionFactory"/>
<property name="destination" ref="QUEUE_NAME"/>
<property name="messageListener" ref="productUpdateListener" />
<property name="sessionTransacted" value="true"/>
<property name="autoStartup" value="true"/>
</bean>
PooledConnectionFactory closes sessions/consumer connection after the consumer has processed messages.Hence the consumer count keeps reducing.
If you are using multithreaded environment its better to use CachingConnectionFactory. But this has some drawbacks as it caches the consumers so if a consumer hangs the client would keep pinging the stalled consumer without knowing that its connection is idle.
Exact solution for your problem, using JMS template is hard to find but you can manually create new connections by checking that if a connection has been closed by using connection.start() or connection.createConnection methods.

DefaultMessageListenerContainer recoveryInterval with specific retry count

We are using Spring Integration in our project and we have a requirement where If IBM MQ goes down then we will have to auto connect to IBM MQ when it is up. We have done this implementation using recoveryInterval option of org.springframework.jms.listener.DefaultMessageListenerContainer class. We have given recovery interval as 6 seconds so every 6 seconds system try to recover the MQ connection but now we have a requirement where we will have to do the autorecover twice only and after that if still MQ is down then stop the inbound adapter.
Is there any way in Spring Integration to mention the auto recovery retry count so that system will try to recover only for that retry count?
Below is my existing configuration.
<bean id="inQ" class="com.ibm.mq.jms.MQQueue">
<constructor-arg value="${mq.inbound.queue}" />
</bean>
<int:channel id="inbound" />
<int-jms:message-driven-channel-adapter
id="jmsIn" channel="inbound" container="messageListenerContainer"
acknowledge="transacted" auto-startup="false">
</int-jms:message-driven-channel-adapter>
<int:service-activator id="mainService"
input-channel="inbound" ref="messageListener" method="onMessage">
<int:request-handler-advice-chain>
<ref bean="retryWithBackoffAdviceSession" />
</int:request-handler-advice-chain>
</int:service-activator>
<bean id="messageListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="mqConnectionFactory" />
<property name="destination" ref="inQ" />
<property name="sessionTransacted" value="true" />
<property name="maxConcurrentConsumers" value="${maxConcurrentConsumers}" />
<property name="concurrentConsumers" value="${concurrentConsumers}" />
<property name="receiveTimeout" value="${receiveTimeout}" />
<property name="recoveryInterval" value="60000" />
<property name="autoStartup" value="${autoStartup}" />
</bean>
Thanks
Sach
As an alternative to the recoveryInterval, you can now specify a Backoff instead (see the docs).
It doesn't provide a mechanism to stop the container but an appropriate backoff can effectively do what you want.
You would then need to programmatically stop/start to kick it off again.

Change property value of a existing bean in spring at run time

I have a web application deployed on Tomcat server. I have the following bean hiveDataSource created in my application-context.xml:
<!-- Hive Data Source for Connection Pooling -->
<bean id="hiveDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="url" value="jdbc:hive2://localhost:10000/demo48" />
<property name="driverClassName" value="org.apache.hive.jdbc.HiveDriver" />
<property name="username" value="hive" />
<property name="password" value="" />
<property name="removeAbandoned" value="true" />
<property name="initialSize" value="5" />
<property name="maxActive" value="20" />
</bean>
I want to change the value of property URL, username and password at run time for bean hiveDataSource. Is there any way to change these property values at runtime?
The documentation says that these fields have protected access, so you wont be able to change their values.
Even if you do, by using reflection or in some other way, it's not likely that data source would just pick up these new values. It would probably have to be restarted or reinitialized in some way.

Hibernate (JPA,JSF 2.0, Spring) switch from HyperSQL to Oracle - Configuration is being ignored

i'm currently in the process of working on a midsized Webproject, using JSF 2.0 with Spring.As IDE i use Eclipse with JBoss Tools. The Webapp is deployed to a Tomcat v7.0 Server.
I use Hibernate/JPA/C3P0/ to connect to the Database (previously HyperSQL) I now tried to switch to an Oracle DB, which i did a number of times before and it never was a problem, however now it seems, that the changed configuartion is just being ignored. When i fire up the Server, it still uses the HyperSQl Driver and the old DB, although i cleaned the workdirectory of Tomcat, removed and redeployed the Webapp (which i built from scratch of course).
The project is split in two, one webapp and one service part. The project are dependent in Eclipse. However, although all of the businesslogic is implemented in the service layer, i can just remove it and the webapp doesn't throw an error and i can start it as if nothing has changed. This tells me that it must be cached somewhere and it is not refreshed on the server...I also deleted the server, added a freshly downloaded instance - still the same thing...Does anyone have an Idea what this could be about?
Here is my service.spring.xml:
<!-- Enable processing of #PersistenceContext and #PersistenceUnit -->
<context:annotation-config/>
<!-- Enable transaction configuration with #Transactional -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Configure a c3p0 pooled data source -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="user"/>
<property name="password" value="password"/>
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="jdbc:oracle:thin:#dburl"/>
<property name="initialPoolSize" value="1"/>
<property name="minPoolSize" value="1"/>
<property name="maxPoolSize" value="10"/>
</bean>
<!-- Configure the JPA entity manager factory with Hibernate -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false"/>
<property name="database" value="ORACLE"/>
<property name="generateDdl" value="true"/>
</bean>
</property>
<property name="persistenceUnitName" value="mygourmet"/>
</bean>
<!-- Configure transaction manager for JPA -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
And my persistence.xml:
<persistence-unit name="mygourmet" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<property name="hibernate.use_sql_comments" value="false" />
<property name="hibernate.connection.autocommit" value="false" />
<property name="hibernate.cache.use_query_cache" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="false" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
I used the exact same configuration on another project and it works like a charm...Any hints are highly appreciated, thank you guys in advance!
Problem solved - i did a mvn clean install, generated new eclipse projects and imported them back into eclipse. It seems the changes in my service module were not recognized by eclipse.

Setup Connection Pooling in Spring MVC

How can I setup connection pooling in Spring MVC? I am working on an intranet website powered by Spring MVC 2.5 and jQuery. This is my first attempt at web development.
I am not sure but, I am only using this in my spring configuration file and I saw this in the Spring MVC step By Step tutorial
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
This looks good during development and connection speed is fast but I am not sure if this will still holds true if many users are concurrently connected.
How can I achieve this? I have read that this is not an optimal connection datasource.
You might want to look at c3p0, which has some powerful configuration and optimization available.
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="..." />
<property name="jdbcUrl" value="..." />
<property name="user" value="..." />
<property name="password" value="..." />
</bean>
Your current setup is correct, all you need to do in order to use basic connection pooling is use a DataSource implementation provided by a connection pooling library, in your case Apache DBCP. See this post for a few links to other alternatives, C3P0 being one of them.
Note that when you actually use the DataSource bean you're injecting wrap it in a SimpleJdbcTemplate or use DataSourceUtils to obtain a Connection - see Spring JDBC Documentation
For connection Pooling
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
//Add this two more parameters
<property name="**initialSize**" value="20" />
<property name="**maxActive**" value="30" />
</bean>
connection pool will create 20 database connection as initialSize is 20 and goes up to 30 Database connection if required as maxActive is 30.

Resources