Clarification regarding EclipseLink JPA properties - java

I am using EclipseLink JPA version 2.6 and I wanted to use connection pool properties to set minimum and maximum connection in persistence.xml file. But I have two different set of properties as follows
<property name="eclipselink.connection-pool.default.initial" value="1" />
<property name="eclipselink.connection-pool.default.min" value="64" />
<property name="eclipselink.connection-pool.default.max" value="64" />
And
<property name="eclipselink.connection-pool.default.initial" value="1" />
<property name="eclipselink.connection-pool.node2.min" value="16"/>
<property name="eclipselink.connection-pool.node2.max" value="16"/>
I have doubt that which set I have to use in persistence.xml file. Anyone suggest me a best possible way for handling multiple connections.

Check the documentation about partitioning your connection pool. If you not plan to partition your pool, the first settings-block is fine. Check the Connection Pool settings for eclipselink.

Related

SQLException: I/O Error: Read timed out

I have a Java Spring application connecting to a SQL Server database.
The connection settings are:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="net.sourceforge.jtds.jdbc.Driver" />
<property name="jdbcUrl"
value="jdbc:jtds:sqlserver://${db.host}:1433/TestDB" />
<property name="user" value="${db.user}" />
<property name="password" value="${db.pass}" />
<!-- these are connection pool properties for C3P0 -->
<property name="minPoolSize" value="10" />
<property name="maxPoolSize" value="100" />
<property name="acquireIncrement" value="5"/>
<property name="maxIdleTime" value="30000" />
</bean>
everything works fine but sometimes I got the following error:
Could not open JDBC Connection for the transaction; nested exception is java.sql.SQLException: I/O Error: Read timed out
I have searched a lot but can't find any clue, any idea or help?
I'm using
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
in my spring-config xml to get my sqlSession, and in the DAO I use:
#Autowired
SqlSession sqlSession;
and then I execute the queries I want. Is it possible that because the connection is not closed that this error exists?
In my case connections were getting dropped when the nightly db backup job triggered. I'm using jtds/sql-server as well. Here is what I did to fix it:
Create/setup a health-check cron job that executes a simple query from within your application, like a short select from. Call it every 10 minutes or so and log the result. It will give you some feedback about when and why this is happening.
Reduce the idle time parameter (maxIdleTime) in your configuration so that old connections get automatically discarded.
Keep in mind that if you don't change the maxIdleTime and you keep multiple connections open, some of them may remain in a bad state even if you are using the health-check function. Quoting from c3p0 documentation:
By default, pools will never expire Connections. If you wish Connections to be expired over time in order to maintain "freshness", set maxIdleTime and/or maxConnectionAge. maxIdleTime defines how many seconds a Connection should be permitted to go unused before being culled from the pool. maxConnectionAge forces the pool to cull any Connections that were acquired from the database more than the set number of seconds in the past.
Another way to setup a health-check call is by using the idleConnectionTestPeriod parameter. Also check this answer which can give you more ideas on how to set it up.

Multi connection pool configurations for different modules in application

Our application has multiple modules, each module use its own schema in the same mysql database. Now I need to make different connection pool configurations for each module because of their different db resource consuming nature, i.e. some module may have 20 active connections at a point of time, but others may just have 1 max. I have searched here and other forums, couldn't find a solution, just this topic is not about multi-tenancy or multi-database, all schemas are in the same db.
Here's the config we have:
<bean id="dataSource" class="our.own.package.RoutingDataSource"> <!-- RoutingDataSource extends spring AbstractDataSource -->
<property name="master" ref="masterDS"/>
</bean>
<bean id="abstractDataSource" abstract="true">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="initialPoolSize" value="#initial.pool.size#" />
<property name="minPoolSize" value="#min.pool.size#" />
<property name="maxPoolSize" value="#max.pool.size#" /> <!-- I want to have different configs for each module in our application -->
</bean>
<bean id="masterDS" class="com.mchange.v2.c3p0.ComboPooledDataSource" parent="abstractDataSource">
<property name="jdbcUrl" value="jdbc:mysql://#host#/" />
<property name="user" value="#user#" />
<property name="password" value="#pwd#" />
<property name="dataSourceName" value="#dbName#" />
</bean>
So now I have two questions:
1) Is it possible to have different connection pool configurations for one datasource in Spring?
2) If I have to go with the multiple datasource way(one datasource for one module), is implementing Spring's AbstractRoutingDataSource the correct way to go?
Thank you!
Ad.1 Your data source is in the fact connection pool so you want to have multiple pools on the top of another pool. You can do it but you will face many other problems.
Ad.2. Yes definitely. You already have RoutingDataSource so this one should be implementation of AbstractRoutingDataSource. Probably you already have logic there to determine current the data source routing key which should be used to do the lookup.

How to use mysql custom port in c3p0 datasource?

I have a mysql running on 3306 port in my local system. and also there is another mysql is running on 13000. while im trying to connect to 13000 instance still it is connecting to 3306 instance. c3p0 datasource is taking the default port and it is simply ignoring the port. so could some one help on this???
Spring bean:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:13000/dbname?autoReconnect=true" />
<property name="user" value="user" />
<property name="password" value="pwd" />
<property name="idleConnectionTestPeriod" value="55" />
<property name="initialPoolSize" value="10" />
<property name="maxIdleTime" value="60" />
<property name="maxPoolSize" value="15" />
<property name="minPoolSize" value="5" />
</bean>
Edit:
Even simple JDBC program is connecting to 3306.
c3p0 doesn't parse JDBC urls or make any assumptions at all about what's in them. It just asks your JDBC driver (via DriverManager, or via a directly instantiated driver if you configure forceUseNamedDriverClass) to return Connections for the supplied URL. The issue is definitely not that c3p0 is ignoring the nondefault port. c3p0 is ignoring it all. It has no idea and doesn't care.
I'd try to verify that the JDBC URL you think you are configuring is the one that is actually getting through to the pools you are making. If you have multiple MySQL instances on the machine, maybe you have conflicting config somewhere. c3p0 dumps its configuration to your application's logs at INFO level on pool initiation. Look for that, and verify that the URL your c3p0 DataSource is using is the URL you intended to configure.
Otherwise, try to check to see whether a call to DriverManager.getConnection( myJdbcUrl ) gets you to the DBMS you want. That's basically what is calling. (It's actually calling DriverManager.getConnection( myJdbcUrl, info ) where info is a Properties object. Unless you've set forceUseNamedDriverClass to true.)
Finally found the issue. The reason is i am using mysql-connector-java.5.1.9.jar, so there is a bug in that connector. So i changed it to latest version then my issue got resolved.
Thanks.

tomcat jdbc pool max active not working?

I use spring jdbc template for app.. and deploy it in tomcat.. I want to use connection pool with tomcat jdbc. My connection configuration is
<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3310/mydb" />
<property name="username" value="***" />
<property name="password" value="***" />
<property name="maxWait" value="10000" />
<property name="removeAbandonedTimeout" value="60" />
<property name="removeAbandoned" value="true" />
<property name="logAbandoned" value="false" />
<property name="initialSize" value="10" />
<property name="maxActive" value="100" />
<property name="minIdle" value="10" />
</bean>
I don't know how, but when I run some test, and check the max thread in mysql, it show that the active thread is more than the maxActive configured in the configuration. So, why the maxActive in the configuration not working? And how to make it work? For example, the maxActive is 100 but when I check in mysql, the active thread is more than the maxActive.
maxActive (int) The maximum number of active connections that can be
allocated from this pool at the same time. The default value is 100
maxIdle (int) The maximum number of connections that should be kept in
the pool at all times. Default value is maxActive:100 Idle connections
are checked periodically (if enabled) and connections that been idle
for longer than minEvictableIdleTimeMillis will be released. (also see
testWhileIdle)
So i should recommend you to use maxIdle too, example:
<property name="maxIdle" value="100">
But maybe there is a problem, if you could show the code of your connection management, it would be helpful.
Here is an interesting link of a connection problem with declarative and programmatic transaction management with Spring: Connection pool problem with Spring and programmatic transaction management
I got the same problem with you and my tomcat version is tomcat 9.
Here is my solution: you should set maxTotal value 100 instead of maxActive.
maxTotal: Maximum number of database connections in pool. Make sure you configure your mysqld max_connections large enough to handle all of your db connections. Set to -1 for no limit.
FROM http://tomcat.apache.org/tomcat-9.0-doc/jndi-datasource-examples-howto.html.

how to check that I am using c3p0 in hibernate?

I am change my hibernate.cfg.xml added new options:
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="show_sql">true</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/pirates</property>
<property name="connection.username">postgres</property>
<property name="connection.password">mmm888</property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="show_sql">false</property>
<property name="hbm2ddl.auto">update</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="hibernate.c3p0.max_size">200</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.generate_statistics">true</property>
and added hibernate-c3p0-4.1.4.Final.yar in my project, but I'm not sure that I'm using c3p0. I can set hibernate.c3p0.max_size = 2 but Hibernate continues to create 400 ( 400 -for example) threads - if it needs to.
how to check that I am using c3p0 in hibernate ?
You are missing this line:
<property name="connection.provider_class"
value="org.hibernate.connection.C3P0ConnectionProvider"/>
This tells Hibernate to use the C3P0 connection pool.
Not sure the above answer is necessary, according to C3P0ConnectionProvider document:
https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/connection/C3P0ConnectionProvider.html
It says:
"A connection provider that uses a C3P0 connection pool. Hibernate will use this by default if the hibernate.c3p0.* properties are set."
Check here.
Generally speaking, applications should not have to configure a
ConnectionProvider explicitly if using one of the Hibernate-provided
implementations. Hibernate will internally determine which
ConnectionProvider to use based on the following algorithm:
If hibernate.connection.provider_class is set, it takes precedence
else if hibernate.connection.datasource is set → Using DataSources
else if any setting prefixed by hibernate.c3p0. is set → Using c3p0
else if any setting prefixed by hibernate.proxool. is set → Using
Proxool
else if any setting prefixed by hibernate.hikari. is set → Using
Hikari
else if hibernate.connection.url is set → Using Hibernate’s built-in
(and unsupported) pooling
else → User-provided Connections
Other than this, the fastest way to check is to go in database server and see whether the idle connection have been created or not.

Categories