We are using a j2ee application with spring framework 2.0. The server used is tomcat 5.5. The database used is mysql. We are using a VPS for hosting our application and we have noticed that the CPU usage increases with more users using our application. The CPU usage does not come down once the users stop using the application. Is it the connections that are not closed properly or is there any other issue?
Here is the servlet.xml configuration for the connections
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/myDB"/>
<property name="username" value="xxxx"/>
<property name="password" value="xxxx"/>
<property name="validationQuery" value="SELECT 1"/>
<property name="testOnBorrow" value="true"/>
</bean>
We have also tried using
<bean id="myDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/myDB"/>
<property name="username" value="xxxx"/>
<property name="password" value="xxxx"/>
</bean>
But both of them cause the same problem. Can anyone help us out quickly? Because we need to correct this issue at the earliest. Thanks in advance.
It is unlikely that high CPU usage be caused by some connection pool issues. It's probably a mistake within your application code. Did you monitored database connections — are they released and closed properly?
By the way, I'd suggest you switch to the native connection pool built in Tomcat. It can be obtained as a standard Java EE resource from the pseudo-JNDI implemented in Tomcat.
Related
I have a Spring Hibernate application on Tomcat.
Connection pool is C3P0
I am rapidly encountering a thread pool maxed out warning from C3P0. Then all requests to the webapp hang.
I am still assuming that somewhere in the code I have missed an #Transaction annotation. I want to debug my code.
Question: Can I access the connection pool via code so I can debug when a connection is released and when it is not released?
UPDATE: Current c3p0 config:
<!-- Hibernate -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="org.postgresql.Driver" />
<property name="jdbcUrl" value="jdbc:postgresql://localhost/ikoda01?useUnicode=true&characterEncoding=utf8" />
<property name="user" value="xxxuser" />
<property name="password" value="xxxxx" />
<property name="acquireIncrement" value="2" />
<property name="minPoolSize" value="3" />
<property name="maxPoolSize" value="50" />
<property name="maxIdleTime" value="600" />
</bean>
Can I access the connection pool via code so I can debug when a connection is released and when it is not released?
Yes
You don't even have to code, that's built in. If you configure c3p0 to debug Connection leaks, it will simply print stack traces of the codepaths that checked out the leaked Connections to your logs.
Update:
<property name="unreturnedConnectionTimeout" value="30" />
<property name="debugUnreturnedConnectionStackTraces" value="true" />
The value you should use for unreturnedConnectionTimeout depends on your application. It should be longer than the longest expected legit use of a Connection, but not the shorter it is, the more quickly you'll get log messages about the leak and the more smoothly your app will work around it. For most web-ish applications, the 30 secs shown above is conservative, clients aren't expected to ever wait around 30 secs for a response, so a timeout safely indicates a Connection leak.
I am developping a Spring MVC web application that use the dbcp database connection pool.
<bean id="datasourceAR_XXX" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="singleton">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:#XXX.XXX.com:1500:SERVICE</value></property>
<property name="maxActive"><value>100</value></property>
<property name="maxIdle"><value>10</value></property>
<property name="username"><value>XXX</value></property>
<property name="password"><value>XXX</value></property>
</bean>
I recently moved the scope of those beans to singleton because the amount of connection per session started to be a bit too much.
The problem is :
Our database is shutting down every sunday and the spring application seems to act strangely by keeping the socket open and does not refresh the connection as I thought it would do.
Is there a way to refresh the beans scoped as singleton in a way that will refresh the connection everyday and not be obliged to relaunch the application every monday?
What you want to do is to configure validation for your connections. When a connection is borrowed from the pool you want to make sure that that connection is valid. For this you can specify the validationQuery property on your datasource.
<bean id="datasourceAR_XXX" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="singleton">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:#XXX.XXX.com:1500:SERVICE</value></property>
<property name="maxActive"><value>100</value></property>
<property name="maxIdle"><value>10</value></property>
<property name="username"><value>XXX</value></property>
<property name="password"><value>XXX</value></property>
<property name="validationQuery" value="select 1 from dual" />
</bean>
See DBCP - validationQuery for different Databases for a list of possible validation queries for different databases.
There are some issues with Commons DBCP and it is pretty old (although there is a DBCP 2.x now). I would suggest moving to a different datasource like HikariCP this datasource is also a JDBC 4.x based datasource which allows for easier connection validation (it is part of the JDBC 4 spec).
<bean id="datasourceAR_XXX" class="com.zaxxer.hikari.HikariDataSource">
<property name="datasourceClassName" value="oracle.jdbc.pool.OracleDataSource"/>
<property name="maximumPoolSize" value="20" />
<property name="username" value="XXX" />
<property name="password" value="XXX" />
<property name="datasourceProperties">
<props>
<prop key="serverName">XXX.XXX.com</prop>
<prop key="port">1500</prop>
<prop key="databaseName">SERVICE</prop>
</props>
</property>
</bean>
If your oracle driver is new enough you don't need a validation query anymore as validation is provided by the driver instead of needing to be done with a query. Next to that you probably have better results with this pool.
Also you might have a bit of a large pool size, nice article/presentation about pool sizing can be found here.
I have created multitenancy application using spring4 hibernate4 and struts2 running in tomcat server. Initially it loading in good speed but when I am refreshing browser it taking long time than expected. (I am thinking that there is a session problem) Please tell me how to fix it?
I have fixed the problem by replacing
<bean class="org.apache.commons.dbcp.BasicDataSource" abstract="true"
destroy-method="close" id="abstractDataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
</bean>
with
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
id="abstractDataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
</bean>
Thanks for all
When uploaded our application on prod server we faced strange behaviour - sometimes it stopped to get data from data base as though the logic and everything was right and local version was working perfect. After remote debugging we found that GenericObjectPool was blocking thread. And after some time spent on searching we found situation that fits our problem.
The pool just got exhausted when filled with 8 connections (default value) and by default it's behaviour is set to block thread when exhausted.
Here is my datamodel-context.xml config of BasicDataSource
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="url_to_db"/>
<property name="username" value="username"/>
<property name="password" value="12211"/>
<property name="defaultAutoCommit" value="false"/>
<property name="poolPreparedStatements" value="true"/>
<property name="initialSize" value="10"/>
<property name="maxIdle" value="5"/>
<property name="testOnBorrow" value="true"/>
<property name="logAbandoned" value="true"/>
</bean>
Found here two solutions - increase max active number or change pool's behaviour.
The first one seems to be simple - set property maxActive in BasicDataSource to some number (please correct me if I am mistaking). This way is unwanted because we can not know the exact number of possible simultanious connections.
It was decided to try the second way - to change behaviour to WHEN_EXHAUSTED_GROW.
So is there any way to configure spring default pool to change it's whenExhaustedAction behaviour? Or should I define my own connection pool for BasicDataSource? If so, please can you provide examples?
I appreciate any comments or advices. Thanks.
I have a complex situation where I have to use 2 different databases, there for I use 2 different transaction managers. Is there a way in Spring to link these transaction managers to work in a single transaction ? In case of an exception on the second dataSource changes on the first should be rolled-back.
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#dummyHost:1521:dummySID" />
<property name="username" value="owner" />
<property name="password" value="password" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#dummyHost2:1521:dummySID2" />
<property name="username" value="owner" />
<property name="password" value="password" />
</bean>
<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource2" />
</bean>
You can use Spring's JtaTransactionManager to make sure both DBs are transacted with a single transaction manager.
Note, you would have to choose an underlying implementation which can either be a container's one: e.g. WebLogic, WebSphere and OC4J, etc.. or a stand alone, even an open source one: e.g. Atomikos.
HOWEVER
XA transaction management complicates things (configuration / performance / problem resolution / maintenance / etc.). And in a lot of cases, it can be avoided by clever patterns.
To get a solid understanding on whether you need to use XA ( e.g. distributed ) transaction manager, take a look at this fantastic article by Spring's own Dave Syer: Distributed transactions in Spring, with and without XA
You need a global transaction manager which supports 2-phase-commit (XA). Several independent and free ones are available. I've used Bitronix in a Spring-based project, but there is also Atomikos, and probably others. See http://en.wikipedia.org/wiki/Java_Transaction_API#Opensource_JTA_implementations
For routing through multiple datasource, You could use abstractRoutingDataSource but if you have requirements like one rollbackack affecting another you would need a JtaTransactionManager for distributed txn management .