Я пытаюсь обновить большой набор строк (около 5M). Сначала я столкнулся с проблемой переполнения кучи, когда в результирующем наборе было выбрано так много строк. Поскольку я не хочу увеличивать размер кучи на этой машине, мне было интересно, есть ли эффективный способ сделать это.
Я попытался установить setFetchSize(Integer.MIN_VALUE)
, но затем, когда я вызываю функцию обновления, я получаю эту ошибку:
Набор результатов потоковой передачи com.mysql.jdbc.RowDataDynamic@2087c268
все еще активен. Никакие операторы не могут быть выданы, когда какие-либо потоковые наборы результатов открыты и используются для данного соединения. Убедитесь, что вы вызвали .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)
...
}
Есть идеи, что можно сделать?
Спасибо