我有一个运行在Tomcat中的JSP报告,该报告遍历用户ID列表,并在Oracle数据库中的表中查询用户信息。用户ID列表可能有1000个左右。
当前设计报告的方式是打开与数据库的一个连接,循环遍历ID,然后关闭数据库连接。我的连接是在Tomcat的server.xml中定义的可池化连接
该报告的用户表示,他们认为在该报告完成之前,该连接可能已被收回,已被放弃。
报告中受影响的代码是:
ds = new Data("database");
for (String userID : users) {
ds.ResetParms();
ds.AddParm("1", userID);
rs = ds.GetResult(sql);
if (rs.next()) {
Associate user = new Associate(rs.getString(1));
user.setFirstName(rs.getString(2));
user.setLastName(rs.getString(3));
user.setTitle(rs.getString(4));
user.setDepartment(rs.getString(5));
user.setStatus(rs.getString(6));
user.setStatusEffectiveDate(rs.getString(7));
results.add(user);
}
rs.close();
rs = null;
}
ds.Disconnect();
我认为这是最好的方法。每次迭代只需要一秒钟的时间,因此我看不到为什么在使用时将其视为废弃。
建议将连接移动到循环内部,并在每次迭代中打开/关闭它:
for (String userID : users) {
ds = new Data("database");
ds.ResetParms();
ds.AddParm("1", userID);
rs = ds.GetResult(sql);
if (rs.next()) {
Associate user = new Associate(rs.getString(1));
user.setFirstName(rs.getString(2));
user.setLastName(rs.getString(3));
user.setTitle(rs.getString(4));
user.setDepartment(rs.getString(5));
user.setStatus(rs.getString(6));
user.setStatusEffectiveDate(rs.getString(7));
results.add(user);
rs.close();
rs = null;
}
ds.Disconnect();
}
我相信这会对数据库造成过多的“压力”,但也许我错了。
我的联系如下:
<Resource name="jdbc/database"
auth="Container"
type="javax.sql.DataSource"
description="database (Oracle)"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@//server_name:1534/schema"
alternateUsernameAllowed="false"
initialSize="2"
minIdle="1"
maxIdle="4"
maxActive="8"
maxAge="28800000"
maxWaitMillis="60000"
testOnBorrow="true"
testOnReturn="false"
testWhileIdle="false"
validationQuery="SELECT 1 FROM dual"
validationQueryTimeout="5"
validationInterval="60000"
timeBetweenEvictionRunsMillis="30000"
minEvictableIdleTimeMillis="600000"
removeAbandoned="true"
removeAbandonedTimeout="60"
logAbandoned="true"
jmxEnabled="true" />
我已通读this SO question,涉及一个类似的问题,建议使用拦截器
p.setJdbcInterceptors(
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+ "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"
+ "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer");
我不确定解决此问题的最佳方法。