Database query hangs after some time - java

I have following database configuration in a Spring project -
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.jdbc.url}" />
<property name="username" value="${db.user}" />
<property name="password" value="${db.password}" />
<property name="maxActive" value="75" />
<property name="initialSize" value="10" />
<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />
<property name="maxWait" value="10000"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
autowire="byName">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
The application runs for some time (30 mins to 2 hours, it varies) and after a while it starts to hang. i.e. The browser keeps on waiting for the server to respond. On checking the logs I found that the application is hung on a database query -
01/22 16:56:03 3024208 [http-bio-8080-exec-2] DEBUG DEBUG org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL statement [SELECT * FROM mytable where id = ?]
The connection to the database is proper as I'm able to interact with it and run queries from commandline or mysql workbench.
What could be the source of the problem? At this point I'm totally at a loss as to which direction I should look in, since no exception gets thrown and there is no stacktrace. What approach would you use to attack this problem?

Have you tried creating a thread dump at the moment that your application hangs?
If you're on linux you could try to do:
$ kill -3 <pid>
The thread dump is written to the standard output. It may logged in the console or /logs/stdout or /logs/catalina.out.

Related

Queries take too long after MySQL fail-over

I have an application that uses MySQL fail-over via a connection url:
jdbc:mysql://172.17.0.4:3306,172.17.0.3:3306/db_name?autoReconnect=true&failOverReadOnly=false
Now when primary db is down then it should move to secondary connection and application flow should work as expected.
Now the problem happens when moving to secondary db. It takes too long to move/execute the queries, causing the flow to take much longer than expected.
I have checked already with db and there's no slow query issues. I guess it's something to do with fail-over and with checking the states. So, any idea what might be causing this issue or how to resolve this delay?
I am also using c3p0 to manage the connections pools. Already tried with initialTimeout and maxReconnects but no luck so far.
DataSource
<bean id="productionDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="description" value="integration_ds"/>
<!-- configuration pool via c3p0-->
<property name="acquireIncrement" value="${datasource.acquireIncrement}"/>
<property name="idleConnectionTestPeriod" value="${datasource.idleConnectionTestPeriod}"/>
<!-- seconds -->
<property name="maxPoolSize" value="${datasource.maxPoolSize}"/>
<property name="maxStatements" value="${datasource.maxStatements}"/>
<property name="maxStatementsPerConnection" value="${datasource.maxStatementsPerConnection}"/>
<property name="minPoolSize" value="${datasource.minPoolSize}"/>
<property name="initialPoolSize" value="${datasource.initialPoolSize}"/>
<property name="maxIdleTime" value="${datasource.maxIdleTime}"/>
<property name="acquireRetryAttempts" value="${datasource.acquireRetryAttempts}"/>
<property name="acquireRetryDelay" value="${datasource.acquireRetryDelay}"/>
<property name="breakAfterAcquireFailure" value="${datasource.breakAfterAcquireFailure}"/>
<property name="debugUnreturnedConnectionStackTraces" value="true"/>
</bean>
Properties
datasource.acquireIncrement=1
datasource.idleConnectionTestPeriod=1000
datasource.maxPoolSize=10
datasource.maxStatements=600
datasource.minPoolSize=5
datasource.initialPoolSize=5
datasource.maxIdleTime=7200
#datasource.acquireRetryAttempts=5
datasource.acquireRetryAttempts=1
#datasource.acquireRetryDelay=5000
#datasource.acquireRetryDelay=1000
datasource.acquireRetryDelay=100
datasource.breakAfterAcquireFailure=false
datasource.maxStatementsPerConnection=3
datasource.checkoutTimeout=100
DAO
private static final String findByAppIdHql = "select app from AppImpl app where app.appId = ?";
final Query query = sf.getCurrentSession().createQuery(findByAppIdHql).setString(0, appId);
query.setCacheable(true);
query.setCacheRegion("app_query_cache");
query.setCacheMode(CacheMode.NORMAL);
List<App> apps = query.list();

Spring Throws "ERROR SqlExceptionHelper: Already closed" after timeout

I have a spring application hosted on to the server (Tomcat 8.5). It goes idle if no one uses it. I already knew that timeout will occur if the DB is in idle state for 8 hours (Default timeout of MySQL). As mentioned in Spring Autoreconnect and Connection lost overnight post i have tried the solution available here.I have tried configuring application.properties but that doesn't bring any solution to the problem.
(PS:I'm not changing anything other than application.properties in my Spring Application).
Well if this
spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 60000
spring.datasource.validationQuery = SELECT 1
or this
spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1
didnt work maybe try this
Post SpringBoot 1.4 names have changed
They have defined new specific namespaces for the four connections pools spring supports: tomcat, hikari, dbcp, dbcp2.
spring.datasource.tomcat.testOnBorrow=true
spring.datasource.tomcat.validationQuery=SELECT 1
If problem doesn't solve even after including properties as in application.properties, Then problem will be solved when including testOnBorrow,validationQuery in application-context.xml located in src/main/resources
<bean name="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driver.classname}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
<property name="initialSize" value="2"/>
<property name="maxActive" value="50"/>
<property name="maxIdle" value="5"/>
<property name="maxWait" value="-1"/>
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="600"/>
<property name="logAbandoned" value="true"/>
<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />
</bean>
The solution is to validate connection thread when it is borrowed from thread pool by enabling testOnBorrow and providing validationQuery.

Unable to configure SB to use MySQL hosted BATCH_* tables

I am having some trouble configuring Spring to use BATCH_* tables hosted by MySQL.
I created the tables ok according to docs however it looks like the code is trying to get a sequence number using the Oracle flavour function.
The error I get is:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown table 'BATCH_JOB_SEQ' in field list
But this is hiding the real problem. I debugged it and its trying to run this code:
select " + getIncrementerName() + ".nextval from dual";
Which is obviously Oracle dialect. I notice that there exists the correct incrementer in my environment here:
org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer()
but its calling
org.springframework.jdbc.support.incrementer.OracleMaxValueIncrementer()
I have setup my data source thus:
<bean id="springDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://10.252.205.5:3306/MASKNG" />
<property name="username" value="MASKNG" />
<property name="password" value="maskng" />
</bean>
Anyone have an ideas as this is a show stopper for us atm
Well, well, I really should RTM a little more...you just have to tell the jobRepository bean what type of DB you are using
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
<property name="dataSource" ref="springDataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="validateTransactionState" value="${jobRepository.validationTransactionState:true}" />
<property name="isolationLevelForCreate" value="${jobRepository.isolationLevelForCreate}" />
<!-- <property name="databaseType" value="oracle" /> -->
<property name="databaseType" value="mysql" />
<property name="tablePrefix" value="BATCH_" />
<property name="lobHandler" ref="lobHandler"/>
</bean>

Can't connect to mysql in centos

I use Spring+Mybatis and try to connect mysql server 5.1 in Centos.
The Connection of mysqldatabase is ok and there is no problem when I'm testing with Test Class.
And There is no problem when connecting MYSQL5.5 in Window Server with same config.
In Connecting to MYSQL5.1 in Centos,
When my web application project make a select query, an exception is occurred.
Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'nmnl.USR' doesn't exist
How can I solve?
This is config in spring-beans.xml.
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<util:properties id="SQL_ERROR_CODE" location="classpath:SQL_ERROR_CODE.properties" />
<util:properties id="APPLICATION_CONFIG" location="classpath:APPLICATION_CONFIG.properties" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.0.99:3306/nmnl?useUnicode=yes&characterEncoding=UTF-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:sqlmap-config.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
Please check whether table USR exist in nmnl database or not. Because exception says table USR not exists in nmnl.
Yeah. I got it.
When i restore database with query,My query is CREATE USR.
I remove this char ` and restore back.
And I changed all table names to UPPER case.
I soled. MySQL in linux has case-sensitive. There is only can choose upper or lower. My queries in mybatis sql map are both lower and upper. So i was changed all to UPPER cases.

How to call rest API(Start Process Instance) for Acitviti in JAVA

This is my java code.
ProcessEngines.getDefaultProcessEngine().getRuntimeService().startProcessInstanceByKey("myclcprocess");
server Details:
Schema Details: Server HMECD000046v,
Schema Name: activiti,
Credentials- root, root,
Proc Definition ID- 'myclcprocess:4:7907'
This is my first simple program. I'm getting NullPointerException. Please any one help me how to configure?. and how to invoke the process?.
need to create Activiti.cfg.xml. In that file need to configure the data source details
Example:
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration" >
<!-- Database configurations -->
<property name="jdbcUrl" value="jdbc:mysql://localhost/activiti" />
<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="root" />
<property name="defaultAutoCommit" value="false" />
</bean>
references:
http://krishnasblog.com/2012/05/07/4/
http://bpmn20inaction.blogspot.in/2010/12/activiti-spring-integration-example.html

Categories