Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java MYSQL/JDBC query is returning stale data from cached Connection

Tags:

java

mysql

jdbc

I've been searching Stackoverflow for an answer but can't seem to find one that doesn't involve Hibernate or some other database wrapper.

I'm using JDBC directly via the MYSQL 5.18 JDBC driver in a Tomcat 6 Java EE app. I am caching Connection objects, but not caching Statement objects. The ResultSets for the query are correctly returning up to date data on the first run. When I change a few rows via PHPMyAdmin or some other external tool, rerun the query, I get stale out-of-date data.

I'm using normal Statements, not PreparedStatements. I've tried ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE. I'm also closing out the result set. These do not solve the problem. I've also tried ResultSet.refreshRows(), but that results in an error because the query has a JOIN clause.

The only thing that clearly solves the problem is closing the Connection and reconnecting to the database, which results in a heavy cost for each query attempt.

Is there a way to reuse Connections without returning stale data?

EDIT: I'm not using transactions for queries at the moment.

Here's the general code.

Connection conn; //created elsewhere and reused
...

String query = "SELECT p.ID as oid,rid,handle,summary,city,state,zip,t.name AS category     
                FROM profiles AS p
                JOIN (terms AS t) ON (p.tid = t.ID)
                WHERE p.ID = 1";

ResultSet resultSet;
Statement s;
synchronized (conn)
{                            
   s = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                           ResultSet.CONCUR_UPDATABLE);                        
   resultSet = s.executeQuery(query);
}

//Iterate over the results using .next() and copy data to another data structure   
List retval = getResults(resultSet);
s.close();

Thanks for the help in advance!

like image 389
ricosrealm Avatar asked Feb 17 '12 03:02

ricosrealm


People also ask

How do I disable MySQL query cache?

To set the size of the query cache, set the query_cache_size system variable. Setting it to 0 disables the query cache, as does setting query_cache_type=0 . By default, the query cache is disabled. This is achieved using a default size of 1M, with a default for query_cache_type of 0.

How do I query cache in MySQL?

MySQL determines the queries to cache by examining the query_cache_type variable. Setting this value to 0 or OFF prevents caching or retrieval of cached queries. You can also set it to 1 to enable caching for all queries except for ones beginning with the SELECT SQL_NO_CACHE statement.

What is cachePrepStmts?

Caching Prepared Statements The MySQL JDBC option cachePrepStmts will cache prepared statements in this way (both client and server prepared statements) as well as cache the "preparability" of a statement. There are some statements in MySQL that are not preparable on the server side.


2 Answers

Turns out it was a matter of uncommited queries. Thanks to Brent Worden for the question about transactions which led me to look around and notice that I had disabled auto commit and was not committing after queries.

So the solutions that worked for me:

conn.setAutoCommit(true);

or

statement.executeQuery(query);
conn.commit();

This allows the queries to be flushed out and stale data is prevented.

like image 66
ricosrealm Avatar answered Sep 20 '22 01:09

ricosrealm


Set the transaction isolation level as below.

conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

like image 22
Gurushanth Avatar answered Sep 20 '22 01:09

Gurushanth