Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一个查询时的小bug,没深入分析是否会影响结果 #124

Closed
yackl opened this issue Jul 18, 2016 · 1 comment
Closed

一个查询时的小bug,没深入分析是否会影响结果 #124

yackl opened this issue Jul 18, 2016 · 1 comment

Comments

@yackl
Copy link

yackl commented Jul 18, 2016

Bug修复建议:
com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractStatementAdapter中的重写的getUpdateCount方法
@OverRide
public final int getUpdateCount() throws SQLException {
int result = 0;
for (Statement each : getRoutedStatements()) {
result += each.getUpdateCount();
}
return result;
}
应该修改为
@OverRide
public final int getUpdateCount() throws SQLException {
int result = -1;
for (Statement each : getRoutedStatements()) {
if(each.getUpdateCount() == -1){
continue;
}
result += each.getUpdateCount();
}
return result;
}

Bug说明:
测试时,发现当多表查询时,每个表中都没有结果时
1、each.getUpdateCount()会返回-1。若多个查询statement均没有结果时,result += each.getUpdateCount()返回-4(2库,表水平分2),此时,会调用org.apache.ibatis.logging.jdbc.ResultSetLogger的invoke(Object proxy, Method method, Object[] params)方法,将resultSet设置为close

2、在org.apache.ibatis.executor.resultset.DefaultResultSetHandler中代码逻辑中,若获取到的getUpdateCount不是-1,会继续返回resultSet,然后继续调用getMetaData
if (stmt.getConnection().getMetaData().supportsMultipleResultSets()) {
// Crazy Standard JDBC way of determining if there are more results
if (!((!stmt.getMoreResults()) && (stmt.getUpdateCount() == -1))) {
ResultSet rs = stmt.getResultSet();
return rs != null ? new ResultSetWrapper(rs, configuration) : null;
}
}

3、此时org.apache.ibatis.logging.jdbc.ResultSetLogger的invoke(Object proxy, Method method, Object[] params)方法,proxy=resultSet{close=true},method=getMetaData,导致异常,异常信息:java.sql.SQLException: Operation not allowed after ResultSet closed

org.apache.ibatis.logging.jdbc.ResultSetLogger相关代码如下
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, params);
}
Object o = method.invoke(rs, params);
if ("next".equals(method.getName())) {
if (((Boolean) o)) {
rows++;
if (isTraceEnabled()) {
ResultSetMetaData rsmd = rs.getMetaData();
final int columnCount = rsmd.getColumnCount();
if (first) {
first = false;
printColumnHeaders(rsmd, columnCount);
}
printColumnValues(columnCount);
}
} else {
debug(" Total: " + rows, false);
}
}
clearColumnInfo();
return o;
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}

@hanahmily
Copy link
Contributor

这是sjdbc没有遵循jdbc规范导致的bug @yackl 您发现的bug非常好 而且反馈的很详细 感谢。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants