问题:
我从DB(MySQL)获得大型ResultSet(超过1 000 000行)并处理每行大约40秒。 总结,我使用ResultSet超过30分钟,我得到的记录少于数据库表中真正包含的记录,没有错误,也没有任何保证。如果我计算该ResultSet的行数,它就没事了(ResultSet的数量= DB的数量)。
mysql服务器或mysql jdbc驱动程序有什么限制吗?
我的代码。它适用于spring框架:
public void query(String query, RowCallbackHandler rowCallbackHandler) throws SQLException {
ResultSet rs = null;
ResultSet rsCount = null;
Statement stmt = null;
Statement stmtCount = null;
try {
stmt = createStatmant();
rs = stmt.executeQuery(query);
if (rs == null) {
log.info("result set is null");
}
stmtCount = createStatmant();
rsCount = stmtCount.executeQuery(query);
int i = 0;
while(rsCount.next()){
i++;
}
log.info("ResultSet size : "+i);
int j = 0;
rs.next();
do{
j++;
rowCallbackHandler.processRow(rs);
}while (rs.next());
log.info("ResultSet size real : "+i);
log.info("ResultSet size fact : "+j);
} catch (SQLException e) {
throw new RuntimeException(e.getMessage());
}finally{
if(stmt!=null){
stmt.close();
}
if(rs!=null){
rs.close();
}
if(rsCount!=null){
rsCount.close();
}
}
}
createStatment:
private Statement createStatmant() throws SQLException {
((BasicDataSource)dataSource).setTimeBetweenEvictionRunsMillis(1000*60*60);
Statement stmt = dataSource.getConnection().createStatement(
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(fetchSize);
stmt.setMaxRows(50000000-1);
return stmt;
}
datasource是类中的全局变量:
private javax.sql.DataSource dataSource;
答案 0 :(得分:0)
你正在将一个可变对象rs传递给你的callbackHandler。确保它没有提前或关闭ResultSet。
您声明了四个可以在方法顶部关闭的对象,但只在底部关闭了三个。不要忘记关闭stmtCount。
我假设您将这一点作为我们利益的故障排除方法,并且您不会在生产中这样做。
1百万行乘以40秒= 40百万秒= 463天。数学不支持你“处理每行大约40秒”的陈述。
在您阅读时,是否有任何外部写入数据库的内容?
如果您能够比较日志中的计数,则表示您没有抛出异常。这是一个有用的线索。