Multithreading - MySQL java connector prepared statement use - java

I have made a java class which runs in it's own thread that works through a queue of mysql queries so that it doesn't block the main application thread. I want to use prepared statements, however if I keep reusing the same prepared statement then if there's two or more of that same prepared statement in the queue (I use the same preparedstatement object for each query of that type), it will have the wrong params. If I make a new preparedstatement each time will it recompile the prepared statement each time it is run or will it detect that it's already been compiled and just execute?

I think you really wont be able to utilize Prepared Statement Pooling feature available in Java connection pooling implementations like Apache DBCP. This is because you are storing prepared statement objects in the queue. If you could store your SQL and paramenters in a custom class instead, and create / execute PreparedStatements in execution thread you can get the benefit of pooling by using something like DBCP
See DBCP configurations docs on how to enable statement pooling (poolPreparedStatements)

will it recompile the prepared statement each time it is run or will
it detect that it's already been compiled and just execute?
It's up to the DBMS, not Java, but the general idea is that it can detect a reuse of an existing compiled statement and pools them under the hood, either in the driver or at the server. See the JDBC 4.0 Specification, #11.6, "Reuse of Statements by Pooled
Connections".

From the java tutorial
If you want to execute a Statement object many times, it usually reduces execution time to use a PreparedStatement object instead.
The main feature of a PreparedStatement object is that, unlike a Statement object, it is given a SQL statement when it is created. The advantage to this is that in most cases, this SQL statement is sent to the DBMS right away, where it is compiled. As a result, the PreparedStatement object contains not just a SQL statement, but a SQL statement that has been precompiled. This means that when the PreparedStatement is executed, the DBMS can just run the PreparedStatement SQL statement without having to compile it first.
http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html#supply_values_ps

Related

Prepared statement ps.executeUpdate() is slow in execution under load

I am currently facing issue on performance of Spring JDBC. I am performing inserts in serie and this is increasing the latency when load is introduced. I am using prepared statements and Hikari CP connection pool.
I have narrowed down the problem which function call in Jdbctemplate class is taking more time.
This is the line - https://github.com/spring-projects/spring-framework/blob/06e352822abc1eb0f5858ca9e79e38f8958e3c63/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java#L546
It is stmt.executeUpdate in UpdateStatementCallback. What can be reason for this?
I have using connection pooling, prepared statement cache & batching as well. I have checked, the underlying Mysql (using AWS RDS) is not a Problem as well.
is there anything I am missing?
spring.datasource.hikari.data-source-properties.cachePrepStmts=true
spring.datasource.hikari.data-source-properties.prepStmtCacheSize=250
spring.datasource.hikari.data-source-properties.prepStmtCacheSqlLimit=2048
spring.datasource.hikari.data-source-properties.useServerPrepStmts=true
spring.datasource.hikari.data-source-properties.useLocalSessionState=true
spring.datasource.hikari.autoCommit=false
spring.jpa.properties.hibernate.jdbc.batchSize=200

Singleton connection + singleton prepared statement

I am implementing a server with MySQL server.
I have come to a conclusion that all my queries will be sent using prepared statements.
I am going to make multiple singleton prepared statements for different purposes(For example, select token, insert/replace token, insert phone numbers ...).
Here are my questions.
For singleton prepared statements to perform well, should I close it every time I execute a query? (close only the ResultSet, not prepared statements or the connection)
Will singleton prepared statement be better than creating a statement every time?
Simple answer - create and close statement every time.
If you are not implementing a VERY specialized batch functionality, then creating and closing prepared statement will be an insignificant overhead.
Also having a singleton connection is not a good idea for server application. Only a single thread can work with one connection at any time.

c3p0 Prepared Statement closed for no apparent reason

I'm using c3p0. I set up a pooled as follows,
cpds = new ComboPooledDataSource();
cpds.setJdbcUrl(...);
/* connection setup */
spds.setMaxStatements(200);
I have an object that prepares several prepared statements on initialization. In order to do that, I grab a connection (con = getConnection()) from the PooledDataSource and then prepare a statement (e.g., PreparedStatement stmt = con.preparedStatemet(/*sql*/)). The prepared statements are stored as private variables in the object and the current connection is closed at the end of initialization (con.close()). The prepared statements are used in methods of the object.
For prepared statements that update the database, this works just fine. However, when I call a method that uses a prepared statement (stmt.executeQuery()) to query the database, I get the following SQLException
java.sql.SQLException: You can't operate on a closed Statement!!!
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:118)
at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:77)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:127)
Did I get something wrong concerning the usage of c3p0?
Many thanks in advance!
Edit: Obviously, my question is partly based on my lack of understanding. As was pointed out in the definite answer, a PreparedStatement belongs to a connection and whenever the connection is closed, the associated statements should be closed, as well. But if that is the case, I don't understand what the use of c3p0's statement cache is.
you should get the same Exception calling executeUpdate(). JDBC Connection and Statement pooling is designed to be transparent: the same API that works for unpooled DataSources should be used for pooled versions too. There will be a dramatic difference in performance, but the code should be semantically interchangeable.
in an unpooled environment, it should be obvious why your approach fails: a Statement, prepared or otherwise, is a child of a Connection, without which it can't function. you are hoping that in the pooled environment, even though the Connection has been "closed", it should still exist in the pool, so hey, those Statements might be good. but that's a very bad idea (and if your attempts to do updates really are succeeding after the parent Connection has been close()ed, again, that'd be a bug, a bad one.) once a Connection has been "closed" it goes back in the pool, but not forever. other clients will check it out, and start performing transaction work that shouldn't be interrupted by your stale Statements. eventually Connections will be expired out of the pool. what should happened to your retained PreparedStatements then?
c3p0 pools Statements transparently, meaning you should use exactly the same API you would have used with no pooling. Call prepareStatement(...) on your Connection, every time. if you've enabled Statement pooling in c3p0 (as you have), then internally c3p0 will check to see whether the Statement has already been prepared, and if so it will quietly use the cached version rather than forwarding the request to the dbms.
i hope this helps!

When should a java PreparedStatement be closed?

In the tutorial "Using Prepared Statements" it states that they should always be closed. Suppose I have a function
getPrice() {
}
that I expect to be called multiple times per second. Should this method be opening and closing the PreparedStatement with every single method call? This seems like a lot of overhead.
First of all, PreparedStatement are never opened. It's just a prepared Statement that is executed. The statement is sent to the RDBMS that executes the SQL statement compiled by the PreparedStatement. The connection to the SQL statement should be opened during the duration of the SQL querying and closed when no other RDMS calls is needed.
You can send many Statement/PreparedStatement as you require provided that you finally close its ResultSet and PreparedStatement once you're completed with them and then close the RDBMS connection.
Should this method be opening and closing the PreparedStatement with every single method call?
If you are creating the PreparedStatement object within the method, then you must close it, once you are done with it. You may reuse the PreparedStatement object for multiple executions, but once you are done with it, you must close it.
This is because, although all Statement objects (including PreparedStatements) are supposed to be closed on invoking Connection.close(), it is rarely the case. In certain JDBC drivers, especially that of Oracle, the driver will be unable to close the connection if the connection has unclosed ResultSet and Statement objects. This would mean that, on these drivers:
You should never lose a reference to a PreparedStatement object. If you do, then the connection will not be closed, until garbage collection occurs. If you are reusing PreparedStatement instances for different SQL statements, it is easy to forget this.
You should close the PreparedStatement once you no longer need it. Only then can the Connection.close() actually tear down the physical connection.
As the example in the tutorial shows you should close it after all your queries have been performed.
Once the statement is closed the RDMS may release all resources associated with your statement. Thus to use it further you'd have to re-prepare the very same statement.
I think that, after every database interaction, every component like statement, resultset must be closed, except for connection, if u tend to perform more operation.
And there is no need to worry, if you are creting the prepared statement again and again, because as you will be using the same statement again and again, there wont be any performannce issue.
Yes..No issues are there if you are creating the prepared statement n number of times, because as you will be using the same statement at all the places. No need to have any observation here regarding performance
Thanks

Oracle jdbc driver: implicit statement cache or setPoolable(true)?

Oracle JDBC driver 11.2.x:
Should I rely on the implicit statement cache or should I invoke setPoolable(true) on each created Statement?
What are the differences, advantages and disadvantages of both methods?
Statement caching improves performance by caching executable statements that are used repeatedly, such as in a loop or in a method that is called repeatedly.
When you enable implicit Statement caching, JDBC automatically caches the prepared or callable statement when you call the close method of this statement object.
Invoking setPoolable(true) on each created statement caches the statement.
I'd say that you're better off relying on the implicit Statement cache.
Here's Oracle's documentation on Statement and Result Set Caching for Oracle 11.2.

Categories

Resources