私は大量の行を更新しようとしています(約5M)。私はまず、結果セットに非常に多くの行がフェッチされるというヒープオーバーフロー問題を発見しました。私はこのマシンでヒープサイズを上げたくないので、これを行う有効な方法があるのだろうかと思っていました。JDBCとMySQLを使用した大きなResultsetの更新
私はsetFetchSize(Integer.MIN_VALUE)
を設定しようとしたが、私は更新関数を呼び出すときに、私はこのエラーを取得する:
[email protected]
がまだアクティブである設定
。ストリーミング結果セットが開いていて、特定の接続で使用されている場合は、ステートメントは発行されません。クエリをさらに試行する前に、アクティブなストリーミング結果セットに.close()
を呼び出していることを確認してください。
私がclose()
を結果セットに呼び出すと、もちろんそれを更新することはできません。ここに私のコードは
public void getRows()
{
Statement stmt = null;
ResultSet rs = null;
int countSpecialChars = 0;
int upper = 0, lower = 0, digits =0;
String pass = null;
int id = 0;
char thisChar;
String query = "select id,pass from datatable";
try {
this.conn.setAutoCommit(false);
stmt = this.conn.createStatement();
stmt.setFetchSize(Integer.MIN_VALUE);
rs = stmt.executeQuery(query);
while (rs.next()) {
pass = rs.getString(2).trim();
id = rs.getInt(1);
for (int i=0; i<=pass.length()-1; i++)
{
thisChar= pass.charAt(i);
if (thisChar >= 65 && thisChar <= 90) {
upper++;
} else if (thisChar >= 97 && thisChar <= 122) {
lower++;
} else if(thisChar >= 48 && thisChar <= 57) {
digits++;
}
else
{countSpecialChars++;}
}
Entropy entropy = new Entropy();
double naiveEntropy = entropy.naiveEntropy(pass);
NumberFormat formatter = new DecimalFormat("#0.00");
this.updateRow(id, pass.length(), digits, upper, lower, countSpecialChars, Double.parseDouble(formatter.format(naiveEntropy)));
countSpecialChars = 0;
upper=digits=0;
lower = 0;
}
rs.close();
}
catch (SQLException e)
...
}
public void updateRow(int id, int length, int numbers, int upper,
int lower, int specialChars, double naiveEntropy)
{
PreparedStatement updatePassEntry = null;
String updateString = "update cwlCompatiblePassUnique " +
"set length = ?, numbers = ?, upper = ?, lower = ?, specialChars = ?, ShannonEntropy = ? where id = ?";
try {
this.conn.setAutoCommit(false);
updatePassEntry = this.conn.prepareStatement(updateString);
updatePassEntry.setInt(1, length);
...
updatePassEntry.setInt(7, id);
updatePassEntry.executeUpdate();
this.conn.commit();
}
catch (SQLException e)
...
}
何ができるかに関するアイデアは?あなたはrs.next()ループ内にupdateRow()メソッドを呼び出し
おかげ
試してみるように閉じることがあります。これが助けてくれることを願う –
これは正解です。 MySQLワイヤプロトコルは、同じ接続上で複数のステートメント実行を同時にサポートしていません。したがって、実際には2つのコマンドが必要な場合は、最初のコマンドの完全な結果を完全に読み取る必要があります(これは「ストリーミングしない」モードです)。または、1つの接続で結果を「ストリーミング」できます。 –