When using Tomcat with MySQL, what is the relationship between poolPreparedStatements setting in Tomcat DataSource configuration (I believe coming from DBCP) and Connector/J cachePrepStmts setting? What's the optimal configuration?
poolPreparedStatements is a setting for the Tomcat JDBC connection pool and cachePrepStmts is a setting for Connector/J to tell MySQL to cache prepared statements. Two completely different things. cachePrepStmts is a per connection setting, but Connector/J doesn't concern itself with whether it's connecting to a database connection pool or to MySQL directly, yet cachePrepStmts works at it's best with persistent connections (e.g. connection pools). To use cachePrepStmts with a connection pool is the optimal configuration. Using poolPreparedStatements in Tomcat is to open a can of memory management worms (check out the Tomcat docs for this setting and you'll see). Really, it's best to let MySQL cache the prepared statements and let Tomcat pool the connections and not try to have one do the other's job.
Related
I have an app that is written in java spring.
It uses hibernate to handle connections to postgres DB.
I want to get the size of the connection pool, but it isn't defined on the app's hibernate configurations.
So I guess it uses hibernate default size, which is 1?
That sounds very low to me.
How can I be sure what is the size of connection pool?
I read that it is recommended to use third party manager for this, but I don't think it's in used also.
I'm trying to check the database connection with jpa using the EntitityManager/Session class.
To check both cases (connected/not connected), I simply start/deactivate the service mysql before running the code.
Asking simple sql queries to the database is out of mind since it doesn't cover all cases.
I already tried:
Session session = entityManager.unwrap(Session.class)
session.isConnected();
But that always returns true...
When I disable the mySQL service I want session.isConnected() to return false, but it always returns true;
Is there any other way to check for the database connection(using any other classes maybe)?
Short answer: don't
Long answer: if you're developing an application where this is important, you will probably be using some sort of database connection pooling framework, like the
Tomcat JDBC pool
Apache Commons DBCP
HikariCP
C3P0 Connection pool
This will manage many important aspects for you, including connection lifecycle. In tomcat jdbc for example you can specify:
testOnBorrow="true"
validationQuery="select 1 from sysibm.dual"
This on an IBM DB2 database will test whether a connection went stale every time you use it, and also swap it out for a fresh one if the select fails. Done this way, you will never have to worry about this on the level of you application code.
I've a Spring Boot Java application in production that uses ActiveJDBC to access a MariaDB database.
If at launch the application boots before the db server, of if the db server crashes and restarts, the apps doesn't re-estabilish the connection with the db.
ActiveJDBC is on version 1.4.13 and if possible I'd prefer not upgrading it, to avoid possible breakages. The db parameters are configured using the database.properties file and typically the usage pattern is:
try {
Base.open();
...
} finally {
Base.close();
}
Is there a way to circumvent this problem, without monitoring and relaunching the application? Maybe using connection pools? If this is the case, are there any docs or examples?
If you are using a direct JDBC connection in your database.properties file, a new connection will be open every time you execute Base.open(). This means that any old connection that is broken is not relevant anymore. If you use a JDNI pool such as:
production.jndi=java:comp/env/jdbc/acme
then you want to configure your containers' pool to ensure that every connection served from the pool is valid just before the pool serves the connection to your app. It is up to the implementation and documentation of your container/pool how to do that.
In any case, I do not think you are going to have issues.
Which of the settings of jdbc pool may help me with killing sql query which runs more than 1 seconds?
When I say tomcat jdbc pool I mean Resource in context.xml in /tomcat/conf/ directory.
It looks like the tomcat pool provides an out-of-the-box interceptor to do this for you. See...
https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#org.apache.tomcat.jdbc.pool.interceptor.QueryTimeoutInterceptor
You should be able to add one of these interceptors to your config
(Note: that document says it is still up to the JDBC driver to enforce query timeouts.)
Is it possible to specify connection/query timeout for the Oracle database queries? Either on Oracle side or in Oracle's JDBC driver (10.2.0.4)? So, that Java client just got an error back after, let's say, 2 minutes instead of waiting until Oracle finishes executing the query?
If you are executing the query in the context of a transaction, the transaction timeout value of the JTA transaction monitor will be the determinant to query timeout. The configuration for this depends from one application server to another.
At an individual query level (in the absence of a JTA transaction monitor), the setQueryTimeout method can be used to set the timeout on the execution of a Statement/PreparedStatement/CallableStatement object.
Update
setQueryTimeout is not to be relied on, although it works (atleast from a J2SE client). It works via the JDBC driver performing a full round-trip to the Oracle database server. Then, it is upto the database to halt execution of the query. Don't rely on it for time critical applications.
Have a look at Oracle profiles. This allows you to specify several limits at the database level. One of them is a maximum CPU time per query.
If you have queries running for more than 2 minutes on a regular basis you might want to do some tuning of your queries first.
According to http://www.javamonamour.org/2012/09/oraclenetconnecttimeout.html
oracle.net.READ_TIMEOUT for jdbc versions < 10.1.0.5 oracle.jdbc.ReadTimeout for jdbc versions >=10.1.0.5
So if you are using a JDBC driver version 10.1.0.5 or higher, then oracle.jdbc.ReadTimeout is the correct property.
Setting oracle.jdbc.ReadTimeout helped to timeout the jdbc calls. I have used it in a production spring boot app by specifying datasource properties as below
spring.datasource.hikari.connection-timeout=1000
spring.datasource.hikari.dataSourceProperties=oracle.jdbc.ReadTimeout=2000
Note: Earlier this app was using tomcat connection pool and after setting the above properties for the same, timeouts were happening but the pool was not able to handle the closed connection objects efficiently. Therefore, I switched to hikariCP and got lot better results. I have made a video simulating the slow jdbc calls which compares the results with tomcat and hikari connection pools while using the ReadTimeout property.