Efficient way to validate a DB connection - java

The DB driver I am working with (for a sybase DB) does not implement a Connection.isValid(). What is the most efficient way I can validate a db connection using a query (or otherwise) in Java?

Libraries such as C3P0 and DBCP allow you to provide a validation query which is typically something very simple such as "select 1". Hence, you could take the same approach or simply use either of these libraries (my recommendation would be C3P0).
However, rather than testing the connection prior to executing your query you could simply attempt to execute and then retry the operation if it fails because the connection is invalid. Alternatively you could consider a non-pooled connection approach where the connection is created on-the-fly each time (e.g. such as Spring's DriverManagerDataSource).

I mostly agree with Adamski's comment about using "select 1 from table" as an efficient way of checking connectivity and using connection pooling (e.g. commons-dbcp, C3PO).
Application servers (e.g. Websphere) allow you to configure this validation for you so your applciation code doesn't have to know about it. You have the choice of always having the connection checked prior to using it, or the connection pool being validated when a new connections is created. You can also purge connections periodically in case they get stale.
If you're not running in an application server you can use Common DBCP with the properties described here:
http://commons.apache.org/dbcp/configuration.html
Or C3PO and take a look at using the idleConnectionTestPeriod property. This link talks about use with Hibernate but its still relevant for C3PO generally
http://community.jboss.org/wiki/HowToConfigureTheC3P0ConnectionPool

Related

How to check if you're still connected to the database with jpa

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.

How to handle re-connects to the DB with ActiveJDBC

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.

Connection pool for dynamic database connections

The problem setup is based on a webservice (Spring/Java, Tomcat7 and MySql) where every user gets their own database, hence each request needs their own connection. As all databases are created dynamically during runtime, configuring them statically before startup is not an option.
To optimise database connection usage, an implementation of a database connection pool would be great, right?
With Java/Spring: How would I create a connection pool for dynamic databases? I am a bit struck by the lack of clean options here!
Problem: Tomcat's Connection Pool (and as far as i understand C3P0 as well) treats each new DataSource instance as a whole new connection pool -> stack-reference
Is it a good idea to create a static datasource with a generic MySql connection (without specifing the database on connection) and use a connection pool with this datasource together with adapted SQL statements?
stack-reference
What about developing a custom persistent database based datasource pool? Any experience with performance here? Any advice? Any libraries that do that?
Or would it be feasable to workaround Tomcat's DataSource problem by creating Tomcat JNDI Datasources dynamically by manipulating it's context.xml dynamically from Java?
I can't believe that there aren't more plain/simple solutions for this. Grails/Hibernate struggles with this, Java/JDBC struggles with this, ... is it such a rare use-case to separate userdata on a user basis by creating user specific databases dynamically? If so, what would be a better setup?
EDIT
Another option is the suggestion from #M.Deinum to use a single configured datasource and dynamically hotswap it for the right connection ->M.Deinum Blog and stack-reference. How does that perform with a connection pool like the ones above?
I believe that HikariCP works without having to specify a single database.
Once the databases are created in runtime, you have to create the pools also in runtime. I am afraid the spring infrastructure is not giving you any help here, as it is tuned for the usual static use case.
I'd have a map of pools:
have a Map < connectionUrlString,List< c3poPool > > map
when requesting a connection, get the corresponding c3po pool from the map
and you can get the best of both worlds, since the real connection pool for each dynamically created database is handled by a c3po instance, but you can create new instances in runtime
This works as a low-level solution. If you want to go further, you can wrap this logic into a db connection provider, and register that as a "driver". This way any part of your application requests a new connection, you can just return one connection from the existing pools (and if a totally new connection is requested, create a new pool for that).
First than all, sorry for my english, i'm improving every day.
In my experience, I had a similar situation and it was resolve with spring framework. Let me explain you how you'd solve that question.
Make a spring config file with these characteristics:
a) A resource loader: This one is the responsible of load properties from configurations files or from database, those properties will be the appropriates to establish the database connection.
b) A pool database configuration parameterized with the properties that you'll load.
Create a locator class: In this class you'll need a HashMap
Use the multi context feature of spring: The idea is assign a code to every one connection that you establish and later load that connection like an application context with spring, then in the locator class, put in the map that context and use it as frequent as you need.
I think is you follow these steps, you can create dynamic pool or database connection as you want.

Does hibernate use PreparedStatement by default

"Hibernate always uses PreparedStatement for calls to the database" Quoted here.
If so then where does hibernate cache compiled queries, does DB driver cache them.
I read about c3p0. If hibernate caches PreparedStatement by default then what is the use of hibernate.c3p0.max_statements in c3p0.
If hibernate does not do it by default then is connection pooling mandatory for caching prepared statements.
Could somebody please clarify these.
Caching prepared statements only makes sense in the scope of a specific JDBC connection. So, you will only gain something out of caching prepared statements when a sort of connection pooling is available to the ORM layer. Otherwise, you get a new "physical" JDBC connection every time you create a Hibernate Session (which is not very efficient normally). Without any connection pooling caching prepared statements is only useful in the scope of a single JDBC connection / Hibernate Session. This happens because without any connection pooling the "physical" connection is actually closed and won't be reused - instead always a new connection will be created using the database driver, whenever it is required.
One other thing that you need to take into account, is that the number of open prepared statements on a single JDBC connection is limited (the limitation is vendor dependent and varies between driver implementations as far as I know). So, in a pooled connections scenario, the pooling implementation will likely need to know how many open prepared statements may be maintained on each of the pool's "physical" underlying JDBC connections. Likely, a "least used prepared statements gets closed first" policy is implemented, but this is pure speculation on my part.
I hope this makes some sense. Whenever I mention a "physical" JDBC connection I mean an actually new TCP/IP connection to the database. Connections obtained by a connection pool will typically decorate/wrap a "physical" one.
Edits to answer your questions more directly:
Hibernate most likely uses and caches PreparedStatements (this is very basic JDBC optimization). The question is does this caching happen on the statements created by a "physical" or a pool provided JDBC connection. Without a pool caching the PreparedStatements only optimizes the part of the application execution that uses a specific PreparedStatement twice in the scope of a specific Hibernate Session. With a pool the same PreparedStatement will (effectively) be used across many Hibernate Session instances that will happen to use the same underlying "physical" connection.
The property hibernate.c3p0.max_statements of your hibernate configuration will most likely configure the C3PO pool instance (which I am pretty sure is created automatically for you) and this configuration has something to do with the fact about the number of open prepared statements being limited in a "physical" JDBC connection.

Oracle connection/query timeout

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.

Categories