Too many connections using c3p0 and hibernate in MySql - java

I'm using c3p0 for my connection pooling. I've configured min connections as 100 and max size as 2000. I'm just writing a simple insert program to check how many connections are active in workbench. But, I'm getting the following error
java.sql.SQLException: Data source rejected establishment of connection, message from server: "Too many connections"
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:650)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:1808)
at com.mysql.jdbc.Connection.<init>(Connection.java:452)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:411)
at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)
at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)
at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
My Hibernate.cfg.xml is as follows
<!-- c3p0 Connection pool config -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.min_size">100</property>
<property name="hibernate.c3p0.max_size">2000</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.c3p0.validate">true</property>
My Java program is
public static void main(String[] args) {
// TODO Auto-generated method stub
Transaction tx = null;
SessionFactory factory = HibernateUtil.getSessionFactory();
Session session = factory.openSession();
tx = session.beginTransaction();
System.setProperty("net.sf.ehcache.skipUpdateCheck", "true");
Employee e = new Employee(2,"Richard");
session.save(e);
try {
Thread.sleep(20000);
} catch (Exception e2) {
e2.printStackTrace();
}
tx.commit();
session.close();
System.out.println("Great! Student was saved");
}
It works fine when the min size is 5 and max size is 20. Do I need to do any changes in MySQL workbench?

The whole purpose of a database connection pool (like c3p0) is to optimise the use of resources versus the database.
If you had 6000 users with 6000 connections, you would quickly exhaust the available connections and errors would result.
Instead, a connection pool allows your application to "borrow" database connections from the pool, and return them after use.
So even though you have potentially 6000 users, the moments of time when multiple users are doing operations that operate versus the database concurrently at that moment in time would be a small fraction of that.
I would suggest to try this as a more reasonable value:
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">100</property>
After setting it up like this, I would run the application and watch the number of connections versus the database. If the 100 connections are at any time exhausted, you could look at tuning it upwards.
But I suspect that 100 concurrent connections will be enough - remember that they are "borrowed" from the c3p0 connection pool.
Documentation: What is c3p0? (connection pooling)

Related

All the threads are waiting on some barrier condition

I have class like this.
class EmployeeTask implements Runnable {
public void run(){
PayDAO payDAO = new payDAO(session);
String newSalary= payDAO.getSalary(empid);
String newTitle= payDAO.getTitle(empid);
EmployeeDAO employeeDAO = new EmployeeDAO(session);
List<Employee> employees = employeeDAO.getEmployees();
employees.parallelStream().foreach(employee-> employeeDAO.add(newSalary, newTitle,employee));
}
}
When I run the above code for one thread, it completes DB operation in 1 second and returns.
When I run it using parallelStream(), it will submit 8 requests, all 8 threads will wait for eight seconds and then return. Which means the server is executing the requests sequentially instead of parallel.
I checked the java jetty logs
Theread-1 Insert …
Theread-2 Insert …
…
Theread-8 Insert …
After eight seconds, that is 1 second per request
Theread-1 Insert … <= update 1
Theread-2 Insert … <= update 1
…
Theread-8 Insert … <= update 1
the same thing continues.
This clearly tells, all the threads are getting blocked on one single resource, either the Datasource from my client java has only one connection so all the eight threads are getting blocked or the server is executing the requests one after the other.
I checked MaxPooledConnections — gives 20, MaxPooledConnections
PerNode - gives 5 default values.
I think the Vertica DB server is fine, maybe client is not having DatasourceConnection pooling, How do I enable Java side DatasourceConnection pooling. Any Code examples?
currently I am using mybatis ORM, with following datasource
<environments default=“XX”>
<environment id=“XX”>
<transactionManager type=“JDBC”/>
<dataSource type="POOLED">
<property name="driver" value="com.vertica.jdbc.Driver"/>
<property name="url" value="jdbc:vertica://host:port/schema”/>
<property name="username" value=“userName”/>
<property name="password" value=“password”/>
<property name="poolMaximumActiveConnections" value=“50”/>
<property name="poolMaximumIdleConnections" value=“10”/>
</dataSource>
</environment>
</environments>
What is the barrier condition all the threads are waiting on, my guess is Datasource connection. Any help is appreciated
Thanks.

Connection is invalid in connection pooling

I am using c3p0 for connection poolingin my java application. We write the all properties related to it and i am having wait_timeout value is 60. We can not increase wait_timeout value. I got error "connection is invalid". How to handle this error.
you should set max_idle_time for waiting timeout ; for example :
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">50</property>
<property name="hibernate.c3p0.timeout">15</property>
<property name="hibernate.c3p0.max_idle_time">60</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.idle_test_period">10</property>
see this link : http://www.mchange.com/projects/c3p0/index.html#configuration_files
you can find same question in stack overflow fro example :
Hibernate c3p0 connection pool not timing out idle connections
c3p0 maxIdleTime is same as wait_timeout of mysql?

Acquired Connections grows abruptly leading to server crash

I have a Java application that schedules a cron job after every 1 min. It runs on Glassfish 4. We are using Hibernate with JTA Entity Manager which is container managed for executing the queries on SQL Server database.
JDBC Connection Pool Settings are:
Initial and Minimum Pool Size:16
Maximum Pool Size:64
Pool Resize Quantity:4
Idle Timeout:300
Max Wait Time:60000
JDBC Connection Pool Statistics after 22 Hours run:
NumConnUsed 0count
NumConnAcquired 14404count
NumConnReleased 14404count
NumConnCreated 16count
NumConnFree 16count
The number of acquired connections keeps on incrementing and the Glassfish 4 crashes after around 10 days with below exception.
RAR5117 : Failed to obtain/create connection from connection pool [ com.beonic.tiv5 ]. Reason : com.sun.appserv.connectors.internal.api.PoolingException: java.lang.RuntimeException: Got exception during XAResource.start:
Please suggest how to avoid Glassfish crash.
finally
{
em = null;
ic = null;
}
I think here is the problem you are never commiting or closing the transacction
Giving this example and documentation of JTA check 5.2.2
// BMT idiom
#Resource public UserTransaction utx;
#Resource public EntityManagerFactory factory;
public void doBusiness() {
EntityManager em = factory.createEntityManager();
try {
// do some work
...
utx.commit();
}
catch (RuntimeException e) {
if (utx != null) utx.rollback();
throw e; // or display error message
}
finally {
em.close();
}
This is the correct way of doing a transacction. But you are only nulling the values and nothing more, that's why you your pools and not being closed
Here is more documentation about Transactions
It's hard to tell what is the real cause of the problem, but the problem might be that all your connections have become stale because not used for a long time.
It is a good practice to set up connection validation, which ensures that connections are reopened when closed by the external server.
There is a thorough article about connection pools in Glassfish/Payara, checkout especially the section about Connection validation (using Derby DB in the example):
To turn on connection validation :
asadmin set
resources.jdbc-connection-pool.test-pool.connection-validation-method=custom-validation
asadmin set
resources.jdbc-connection-pool.test-pool.validation-classname=
org.glassfish.api.jdbc.validation.DerbyConnectionValidation
asadmin
set
resources.jdbc-connection-pool.test-pool.is-connection-validation-required=true

Java. Cannot open connection

I'm using
oracle.ucp.jdbc.PoolDataSource
for getting connections. Each connection wrapped to custom class (historic solution). Generally connection is getting by entityManager. My system require hight performance processing. There is ThreadPool using for it. Thread pool can provide 15 threads at the same time, like connection pool.
Every thing works fine, but sometimes i get exception (in this moment were used only 4 connections):
2012-09-26 17:51:45.835 | ERROR | ThreadExecutor-7 | org.hibernate.ejb.AbstractEntityManagerImpl | Exception in thread "ThreadExecutor-7"
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Cannot open connection
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1235)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1245)
at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:63)
...
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.hibernate.exception.GenericJDBCException: Cannot open connection
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:52)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:449)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1463)
at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:60)
...
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
If i synchronize specified getConnection performance of the system going down 8-12 times.
Is any ideas for fix?
Please check you are setting appropriate values for
<property name="minPoolSize" value="5"/>
<property name="maxPoolSize" value="100"/>//Change if you want
<property name="initialPoolSize" value="5"/>
<property name="validateConnectionOnBorrow" value="true"/>
<property name="maxStatements" value="10"/>
You can check configuration here
You should change connection pooling in hibernate.
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html
Hibernate's own connection pooling algorithm is, however, quite rudimentary. It is intended to help you get started and is not intended for use in a production system, or even for performance testing. You should use a third party pool for best performance and stability. Just replace the hibernate.connection.pool_size property with connection pool specific settings. This will turn off Hibernate's internal pool. For example, you might like to use c3p0.
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50

How to avoid MySQL connection timeout errors with EclipseLink?

MySQL closes a connection after a certain time if nothing happens (8 hours by default). The time can be influenced by the wait_timeout variable in the configuration.
I have an Eclipse RCP application where I use EclipseLink as persistence framework and I get an error when the client exceeds the timeout:
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:
No operations allowed after connection closed.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
...
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
...
com.mysql.jdbc.ConnectionImpl.throwConnectionClosedException
...
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor...
I tried to set autoReconnect/autoReconnectForPools=true but this does not help.
Thanks
EDIT
In my persistence.xml I have the following properties set:
<property
name="eclipselink.jdbc.read-connections.max"
value="10" />
<property
name="eclipselink.jdbc.cache-statements"
value="true" />
<property
name="eclipselink.jdbc.read-connections.shared"
value="true" />
The rest of the configuration is done in the code:
Map<Object, Object> map = ...
map.put(PersistenceUnitProperties.JDBC_URL,...);
map.put(PersistenceUnitProperties.JDBC_USER,...);
map.put(PersistenceUnitProperties.JDBC_PASSWORD, ...);
map.put(PersistenceUnitProperties.JDBC_DRIVER, ...);
map.put(PersistenceUnitProperties.CLASSLOADER, this.getClass()
.getClassLoader());
map.put(PersistenceUnitProperties.TARGET_DATABASE, "MySQL");
entityManagerFactory = new PersistenceProvider()
.createEntityManagerFactory("...", map);
EclipseLink should auto reconnect dead connections. EclipseLink will trap the error, test the connection and if dead reconnect and possibly retry the query (if outside a transaction).
But this depends on what connection pooling you are using, what is your persistence.xml.
The easiest way to do this would be to spawn a thread that sends some sort of keepalive or simple query every hour or so. Here, we would leave a flag so the thread can be shut down on program exit, db change, etc. If it needs to respond faster to that type of shutdown, you can change the counter in the for loop and the sleep time.
boolean parentKilledMe = false;
while (!parentKilledMe){
//put query here
for (int x = 0; x < 360 && !parentKilledMe;x++){
try{
Thread.sleep(6000);
} catch (InterruptedException e) {
//your error handling here
}
}
}

Categories