こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

-広告-

解決済みの質問

JAVAからMYSQL使用時のキャッシュ無効化方法

以下のようにJAVAからMYSQLを使っています。
しかし、30秒おきに使用しているSQL文の結果がDBを更新してもかわりません。

おそらく、javaまたはMYSQLでキャッシュが残っているためだと思うのですが、その無効化方法がわかりません。
その無効化方法のご教授をお願い申し上げます。


//MYSQLの各種設定
public onlineCycleChkDao() {

// JDBCドライバの指定
this.driver = "com.mysql.jdbc.Driver";

// データベースの指定
this.server = "xxxx"; // MySQLサーバ ( IP または ホスト名 )
this.dbname = "xx"; // データベース名
this.url = "jdbc:mysql://" + server + "/" + dbname + "?useUnicode=true&characterEncoding=UTF8";
this.user = "xxxxxx"; // データベース作成ユーザ名
this.password = "xxxxxx"; // データベース作成ユーザパスワード

DBcon();

try{
stmt = con.createStatement();
} catch(SQLException e){
System.err.println("SQL failed.");
e.printStackTrace();
System.exit(2);

}
}

private void DBcon(){

try{
// JDBCドライバの登録
Class.forName(this.getDriver());

// データベースとの接続
con = DriverManager.getConnection(getUrl(), getUser(), getPassword());
con.setAutoCommit(false);

} catch(SQLException e){
System.err.println("SQL failed.");
e.printStackTrace();
System.exit(2);

} catch(ClassNotFoundException ex){
ex.printStackTrace();
System.exit(2);

}
}

public void closeConnection(){

// コネクション切断
try{
con.close();

} catch(SQLException e) {
System.out.println("MySQL Close error.");

}
}



//サイクルSQL
private long selectMaxSeqNo(String table){
long maxSeqNo = -1;
try{
ResultSet rs;

String sql;

sql = "SELECT SQL_NO_CACHE SEQ_NO, NOW() FROM " + table ; //ここの取得結果が更新されません。対象テーブルは他のプログラムにて更新
sql += " ORDER BY RGST_TIME DESC limit 1;";

rs = stmt.executeQuery(sql);
System.out.println(sql);
while(rs.next()){
maxSeqNo = rs.getInt("SEQ_NO");
}
rs.close();

} catch(SQLException e){
System.err.println("SQL failed.");
e.printStackTrace();
System.exit(2);
}
System.out.println("seqNo:" + maxSeqNo);
return(maxSeqNo);
}

public ArrayList<Long> selectMaxSeqNoList(){
//対象テーブルから最新のシーケンスNoリストを取得する。
ArrayList<Long> seqNoList = new ArrayList<Long>();

for(String Table : TableList){
//最新のシーケンスNo取得
long recentSeqNo = selectMaxSeqNo(Table);

seqNoList.add(recentSeqNo);
}
return(seqNoList);
}

投稿日時 - 2015-12-30 08:59:01

QNo.9103434

すぐに回答ほしいです

質問者が選んだベストアンサー

>30秒おきに使用しているSQL文の結果が
とありますが、データベースとの接続は毎回行っていますか?
それとも、接続しっぱなしですか?

もし、接続しっぱなしの場合は、トランザクションの分離レベル(隔離レベル、遮断レベルなど)の問題かもしれません。
接続しっぱなしでない場合は、以下は無視してください。


MySQLのデフォルトの分離レベルは「REPEATABLE READ」だそうなので、トランザクション実行中は、一度読みだした値は他のトランザクションが変更しても、変更前の値のままになります。

JAVAのAPIによると、REPEATABLE READになっている場合、
1つのトランザクションがある行を読み込み、2番目のトランザクションがその行を変更した場合に、最初のトランザクションがその行を読込みし直したときに2度目は異なる値を取得するという状況が禁止されます
だそうです。
http://docs.oracle.com/javase/jp/8/docs/api/java/sql/Connection.html#TRANSACTION_REPEATABLE_READ

なので、分離レベルを「READ COMMITTED」などに下げれば解決しそうですが、そうすると、他の問題が出てくるかもしれませんので、十分注意してください。それよりも、接続しっぱなしをやめた方がいいかもしれません。

分離レベルを変更するためには、Connection の setTransactionIsolation で設定します。
http://docs.oracle.com/javase/jp/8/docs/api/java/sql/Connection.html#setTransactionIsolation-int-

トランザクションの分離レベルの話は、このブログがわかりやすそうです。
http://gyouza-daisuki.hatenablog.com/entry/2013/11/19/150838

投稿日時 - 2015-12-31 15:15:07

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(2)

ANo.1

更新しているプログラムでcommitしていますか?
insertしているレコードを読むならこのプログラムでcommitかrollback
すればよいかと。

投稿日時 - 2015-12-30 09:20:07

補足

commitというのはinsertでということでしょうか。

insertのプログラムは、以下の通りです。

query = "LOAD DATA LOCAL INFILE '" + dataFile + "' INTO TABLE " + テーブル名 + " FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';"
cursor.execute(query)
connection.commit()

上記は一部ですが、commitしているので問題ないと思います。

投稿日時 - 2015-12-30 12:29:01

-広告-
-広告-
-広告-
-広告-