I'm experiencing a weird behaviour with our Java web application, configured to access a PostgreSQL database through C3p0 ComboPooledDataSource.
First of all, PostgreSQL server installation has default parameters, we didn't need to change any variable in it..
We run our queries using Spring JdbcTemplate, version 3.2.12.RELEASE. As it is for PostgreSQL, it is configured with default parameters.
Here it is our context configuration with C3p0 and Spring;
<bean id="resoilDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<!-- access configuration -->
<property name="driverClass" value="org.postgresql.Driver" />
<property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/*****" />
<property name="user" value="******" />
<property name="password" value="******" />
<!-- pool sizing -->
<property name="initialPoolSize" value="1" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="6" />
<property name="acquireIncrement" value="3" />
<property name="maxStatements" value="150" />
<!-- refreshing connections -->
<property name="maxIdleTime" value="180" /> <!-- 3min -->
<property name="maxIdleTimeExcessConnections" value="120" /> <!-- 3min -->
<!-- timeouts e testing -->
<property name="idleConnectionTestPeriod" value="120" /> <!-- 60 -->
<property name="testConnectionOnCheckout" value="true" />
<property name="testConnectionOnCheckin" value="false" />
<property name="preferredTestQuery" value="SELECT 1" />
</bean>
<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="resoilDataSource"></property>
</bean>
Let me describe the problem we are encountering:
once we reach "maxPoolSize" of idle connections opened on Postgres side, this connections never expires, they remain in "idle" state and there's no way C3p0 will get any of them back for pooling..
I would expect that once one of these opened connections excess idle time, C3p0 is able to reuse it due to the "maxIdleTimeExcessConnections" parameter.
Unfortunately, this never happens.
I also tried to substitute C3p0 ComboPooledDataSource with Apache DBCP BasicDataSource, but nothing changed.
Before using PostgreSQL database for our application, our customers asked us to install our application integrating other popular databases instead of PostgreSQL (SQL Server and Oracle in particular) and we never experienced this behaviour.
Any ideas about what's going on it's truly appreciated, thanks in advance.
Related
I have soap webservice written in Spring 2.X and which connect to Teradata and return the result to client. To connect the data based I am using Tomcat JDBC Connection Pool as the DataSource.
In peak hour (9AM to 6PM) application get about 60k transactions requests. I observed some of the transactions goes in hung state and return response in 2-3 minutes . I suspect some transaction goes in wait status and once connection is available in pool then complete the transactions.
Below is the configuration for the DataSource.
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
destroy-method="close">
<property name="driverClassName" value="com.teradata.jdbc.TeraDriver"/>
<property name="url" >
<util:constant static-field=" _DB_HOST"/>
</property>
<property name="username">
<util:constant static-field=" DB_USER"/>
</property>
<property name="password">
<util:constant static-field=" DB_PWD"/>
</property>
<property name="initialSize" value="1" />
<property name="maxActive" value="50" />
<property name="minIdle" value="0" />
<property name="maxWait" value="-1" />
<property name="minEvictableIdleTimeMillis" value="1000" />
<property name="timeBetweenEvictionRunsMillis" value="1000" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
<qualifier value="txnMngr"/>
</bean>
// using JdbcTemplate to read the data from data base.
Here are my questions:
Is there any issue with above configuration based on the load which I mentioned for my application?
Is there any way I can monitor the DB connection pool uses?
I have legacy web application. Witch uses jdbcTemplate to execute stored procedures from DB (Oracle), procedures located at packages. Problem is, when database developers compiles that packages im getting Expceptions sometihng like existing state of packages been changed (ora 4061). and they does that 1 or 2 times per week. Then i have to restart application to restart pool. app uses OracleDataSource. i can't change anything at that db but can change pool manager. so the question is. is it possible to close that connection? not just return to pool. and get new connection(from pool) if that Exception apears? thanks !!
people sugested to re-execute that stored procedure when that error apears. It doest worked.
<bean id="ds_name" class="oracle.jdbc.pool.OracleDataSource"
destroy-method="close">
<property name="connectionCachingEnabled" value="true" />
<property name="URL" value="****" />
<property name="user" value="user" />
<property name="password" value="pass" />
<property name="connectionCacheProperties">
<value>
MinLimit:1
MaxLimit:100
InitialLimit:1
ConnectionWaitTimeout:120
InactivityTimeout:180
ValidateConnection:true
</value>
</property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds_name" />
</bean>
I'm trying to use hibernate jpa and hikaricp for the CP.
But I have an issue that I dont understand, so either my config is bad ... or I do have something else.
this is the config In have in my persistence.xml file :
<properties>
<!-- SQL -->
<property name="hibernate.dialect" value="org.hibernate.spatial.dialect.mysql.MySQLSpatialDialect" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.format_sql" value="false" />
<!-- HikariCP -->
<property name="hibernate.connection.provider_class" value="com.zaxxer.hikari.hibernate.HikariConnectionProvider"/>
<property name="hibernate.hikari.driverClassName" value="com.mysql.jdbc.Driver" />
<property name="hibernate.hikari.minimumIdle" value="5"/>
<property name="hibernate.hikari.maximumPoolSize" value="30"/>
<property name="hibernate.hikari.maxLifetime" value="150000"/>
<property name="hibernate.hikari.dataSource.user" value="user" />
<property name="hibernate.hikari.dataSource.password" value="password" />
<property name="hibernate.hikari.jdbcUrl"
value="jdbc:mysql://server:3306" />
</properties>
Still I'm having 100+ connections on the database. I thought that using maximumPoolSize it would have limit my number of connections. Is my configuration OK, based on my research it seems ok to me, but before trying to debug elsewhere I want to make sure it is.
Thanks
You must be missing the hibernate-hikari module jar on your classpath. This module is necessary to integrate hibernate with HikariCP
Here is the official documentation
Am New to spring batch. with spring batch job i am inserting data in postgres db then i am getting this error . how to fix this?
Method org.postgresql.jdbc3.Jdbc3PreparedStatement.setQueryTimeout(int) is not yet implemented.; nested exception is java.sql.SQLException: Method org.postgresql.jdbc3.Jdbc3PreparedStatement.setQueryTimeout(int) is not yet implemented.'
This is my datasource code.
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<!-- DB connection properties -->
<property name="driverClass" value="${db.driver:oracle.jdbc.OracleDriver}" />
<property name="jdbcUrl" value="${db.url}" />
<property name="user" value="${db.user:}" />
<property name="password" value="${db.password:}" />
<!-- Pool sizing properties -->
<property name="initialPoolSize" value="${db.pool.initialSize:5}" />
<property name="maxPoolSize" value="${db.pool.maxSize:25}" />
<property name="minPoolSize" value="${db.pool.minSize:0}" />
<property name="maxStatements" value="${db.pool.maxStatements:10}" />
<!-- Connection testing and acquisition properties -->
<property name="maxIdleTime" value="${db.con.maxIdleTime:300}" />
<property name="idleConnectionTestPeriod" value="${db.con.testPeriod:30}" />
<property name="preferredTestQuery" value="${db.con.testQuery:select 1 from dual}" />
<property name="acquireIncrement" value="${db.con.acquireIncrement:5}" />
<property name="acquireRetryAttempts" value="${db.con.retryAttempts:0}" />
<property name="acquireRetryDelay" value="${db.con.retryDelay:3000}" />
<!-- JMX name -->
<property name="dataSourceName" value="Datasource" />
<!-- Debugging options -->
<property name="unreturnedConnectionTimeout" value="${db.con.unreturnedTimeout:0}" />
<property name="debugUnreturnedConnectionStackTraces" value="${db.con.debugUnreturned:false}" />
</bean>
The data source looks OK.... #duffymo, the Oracle driver is the default, but would be overridden by the value of 'db.driver' property if 'db.driver' is specified.
The setTimeout error is thrown by some versions of the PostgreSQL driver because they have not, in fact, implemented setTimeout, so they don't want users thinking the setTimeout actually has any effect.
What version of the PostreSQL driver are you using? Can you share some details of the Spring Batch job? I'm not sure how to prevent Spring from setting the timeout on a PreparedStatement. At a guess, you could set db.con.unreturnedTimeout to 0; I'm thinking that value may be passed to setTimeout; but I'm not sure.
I am currently in the process of upgrading an application from Hibernate 3.2 to Hibernate 3.3. I though I'd stick with the default connection pool (Hibernate changed its default from Commons DBCP to c3p0) as I don't have any good reason to choose a non-default pool. At least non but having used DBCP before.
The upgrade went pretty much without any problems so far. The only thing I can't get to work is passing properties to the underlying MySQL JDBC4Connection. Up to now, I used DBCP's BasicDataSource.addConnectionProperty(String,String) to pass properties (useUnicode=true, characterEncodin=UTF-8, characterSetResults=UTF-8, zeroDateTimeBehavior=convertToNull).
However, I can't find any way to do the same with c3p0 other than including them in the JDBC URL. (That's something I'd like to avoid as I wanna keep the URL configurable without forcing users to include those parameters.)
So far, I've tried to use a ConnectionCustomizer without success. Any other suggestions?
Once again a question I answer myself (another self-learner? yes, please!):
com.mchange.v2.c3p0.ComboPooledDataSource has a property "properties". Interestingly, setting properties after user and password overrides them. But setting properties before user and password works as expected.
Follow up for the self answer.
An example of a spring way of configuring this:
The Data source bean:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="properties" ref="mysqlConnectionProperties"></property>
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- c3p0 combo pooled data source settings -->
<property name="initialPoolSize" value="3" />
<property name="minPoolSize" value="3" />
<property name="maxPoolSize" value="50" />
<property name="maxIdleTime" value="7200" />
<property name="maxStatements" value="200" />
<property name="idleConnectionTestPeriod" value="270" />
<property name="preferredTestQuery">
<value>SELECT 1</value>
</property>
</bean>
The properties bean:
<bean id="mysqlConnectionProperties" class="java.util.Properties">
<constructor-arg>
<props>
<prop key="useTimezone">true</prop>
<prop key="serverTimezone">America/Chicago</prop>
<!-- add any other properties you have -->
</props>
</constructor-arg>
</bean>