ibatis 3.0 只创建不回收的BUG

前两天刚解决了[url=http://xsldlm.iteye.com/admin/blogs/511666] IBatis.NET,不要相信它,内存疯狂泄漏[/url] 的bug....决定立即升级到最近版本 3.0.
结果今天又见一个BUG.:程序运行几分钟后,出现错误(oracle):打开游标数超过最大值
很明显,打开太多的Statement而没有关闭,不多说直接看源码(本人对于这种清理不干净的问题极其过敏)

[size=large]一、问题[/size]
系统运行一段时间后,报(oracle):打开游标数超过最大值
[size=large]二、原因[/size]:[color=red]BATCH模式的executor对所有select操作产生的Statement未执行close操作[/color]。
SIMPLE的CRUD不存在此问题,但BATCH的所有select操作均未close。看三个关健方法代码:

// BatchExecutor.java 文件
public int doUpdate(MappedStatement ms, Object parameterObject)
throws SQLException {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null);
BoundSql boundSql = handler.getBoundSql();
String sql = boundSql.getSql();
Statement stmt;
if (currentSql != null && sql.hashCode() == currentSql.hashCode() && sql.length() == currentSql.length()) {
int last = statementList.size() - 1;
// 添加 statement
stmt = statementList.get(last);
} else {
Connection connection = transaction.getConnection();
stmt = handler.prepare(connection);
currentSql = sql;
statementList.add(stmt);
batchResultList.add(new BatchResult(ms, sql, parameterObject));
}
handler.parameterize(stmt);
handler.batch(stmt);
return BATCH_UPDATE_RETURN_VALUE;
}

public List doQuery(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler)
throws SQLException {
flushStatements();
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, rowBounds, resultHandler);
Connection connection = transaction.getConnection();
Statement stmt = handler.prepare(connection);
handler.parameterize(stmt);
try{ // 在这里添加两行代码,以close相关Statement
return handler.query(stmt, resultHandler);
}finally{ closeStatement(stmt); } // add end.
}

// 这个方法在 commit 时会调用
public List<BatchResult> doFlushStatements() throws SQLException {
List<BatchResult> results = new ArrayList<BatchResult>();
try {
for (int i = 0, n = statementList.size(); i < n; i++) {
Statement stmt = statementList.get(i);
BatchResult batchResult = batchResultList.get(i);
。。。。。省
results.add(batchResult);
}
return results;
} finally {
for (Statement stmt : statementList) {
// 在这里 close 批处理所用的 Statement
closeStatement(stmt);
}
currentSql = null;
statementList.clear();
batchResultList.clear();
}
}


[size=large]三.解决方法[/size]
上面代码已经给出相关说明。Batch模式对于更新操作会在commit时关闭,而 batch 模式对于select 操作是无效的,我们应该在做完select操作后直接将其close
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值