2012-02-17 10 views
5

私は答えとしてStackoverflowを探していましたが、Hibernateやその他のデータベースラッパーに関係していないものは見つかりませんでした。Java MYSQL/JDBCクエリがキャッシュされたConnectionから古くなったデータを返しています

Tomcat 6 Java EEアプリケーションのMYSQL 5.18 JDBCドライバを使用してJDBCを直接使用しています。私はConnectionオブジェクトをキャッシュしていますが、Statementオブジェクトはキャッシュしていません。クエリのResultSetは、最初の実行時に最新のデータに正しく戻ります。 PHPMyAdminや他の外部ツールを使用していくつかの行を変更した後、クエリを再実行すると、古くなった古いデータが取得されます。

私はPreparedStatementsではなく、通常のステートメントを使用しています。私はResultSet.TYPE_SCROLL_SENSITIVE、ResultSet.CONCUR_UPDATABLEを試しました。私は結果セットもクローズしています。これらは問題を解決しません。私もResultSet.refreshRows()を試しましたが、クエリにJOIN句があるためにエラーが発生します。

問題をはっきりと解決するのは、Connectionを閉じてデータベースに再接続することだけです。その結果、クエリの試行ごとにコストが高くなります。

古いデータを返さずにConnectionsを再利用する方法はありますか?

EDIT:現時点では、クエリにトランザクションを使用していません。

ここに一般的なコードがあります。

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(); 

ありがとうございました!

+2

トランザクションを使用していますか?もしそうなら、分離レベルは何ですか? REPEATABLE READのような感じです。 –

+0

良い質問です。これらのクエリのトランザクションはありません。私は一般的に更新/挿入のトランザクションを使用していますが、この特定のケースでは、今のところアプリ内では何も実行していません。私は物事を投げ捨てているかもしれない外部ツールを使って更新をしています。汚れた読み取りを防ぐためのソリューションとしてトランザクションを推奨する場合は、回答を共有してください。また、私は接続の分離レベルを設定していません。それが問題だろうか? – ricosrealm

答えて

9

です。これは、コミットされていないクエリの問題でした。私の周りを見回すようになったトランザクションに関する質問に対するBrent Wordenのおかげで、私は自動コミットを無効にし、クエリの後にコミットしていなかったことに気付きました。

私のために働いていたので、解決策:

conn.setAutoCommit(true); 

または

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

これは、クエリがフラッシュアウトすることができますし、古いデータが防止されます。

+0

これを回答としてマークしてください。そのようにして、人々はこの記事を見つけて、あなたの問題と解決策を読むことができます:)。 –

+0

私は2日後になります。私は現時点ではサイトが私を許可しないので、私はできません。 – ricosrealm

+0

あなたは 'conn.commit();'を意味しますか? –

0

Apache DBUtilsを使用してJDBCプールを使用しないでください。同じ接続を使用したり、接続サイズを制御したりすることができます。リンクはhttp://commons.apache.org/dbutils

+0

ポインタありがとうございます。私はこのコードを試してみることができます。しかし、私は大きなコードラッパーを使わないでここで非常に簡単なことをしようとしています。 – ricosrealm

3

以下のようにトランザクション分離レベルを設定します。

connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

1

私のMySQLのインストール:ENGINE = InnoDBは、デフォルトのtx_isolation = REPEATABLE_READ

spring.xml

<tx:method name="find*" propagation="SUPPORTS" read-only="true" timeout="600" /> 

場合、常に同じ結果を返します使用プールされた接続!

変更mysql tx_isolation = READ_COMMITTEDは私の問題を解決しました。

関連する問題