【发布时间】:2011-09-20 02:17:09
【问题描述】:
我正在尝试更新一大组行(大约 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)
...
}
关于可以做什么的任何想法?
谢谢
【问题讨论】:
-
尝试创建一个新连接并使用该连接更新到数据库。希望这会有所帮助。
-
这是正确答案。 MySQL 有线协议不支持同时在同一个连接上执行多个语句。因此,如果确实需要 2 个命令,则必须完全读取第一个命令的完整结果(这是“非流式传输”模式),或者您可以使用一个连接“流式传输”结果,并通过第二个连接进行更新。
标签: java database jdbc resultset