我正在使用 java 8 和 Spring 4 重构一些以前使用 java 5 和 JDBC 调用的代码。对于存储过程调用,我创建了扩展 org.springframework.jdbc.object.StoredProcedure 的类。构造函数设置参数,执行将 2 个参数放在输入映射上,并使用输入参数映射在父类(super class)上调用执行。
存储过程运行一段时间,但它唯一返回的是单个数字返回代码。它正在调用其他存储过程来在数据库中移动数据。但似乎我的调用正在泄漏内存,因为如果我运行足够大的数据集,它就会开始抛出 java.lang.OutOfMemoryError: java heap space
。
最重要的是存储过程没有任何变化,旧代码可以处理使用相同数量的数据调用存储过程而不会耗尽内存。我猜测 StoredProcedure 类中缺少或设置了某些内容导致了问题,但我不确定是什么,因为我对该框架还很陌生。
存储过程类:
public class Extract extends StoredProcedure {
private static final String PARAM_1 = "@PARAM_1";
private static final String PARAM_2 = "@PARAM_2";
public Extract(DataSource dataSource, String sprocName) {
super(dataSource, sprocName);
declareParameter(new SqlOutParameter(Constants.STORED_PROC_RETURN_CODE, Types.VARCHAR, null,
new SqlReturnType() {
public Object getTypeValue(CallableStatement cs, int paramIndex, int sqlType, String typeName)
throws SQLException {
final Integer retCode = cs.getInt(paramIndex);
return retCode;
}
}));
declareParameter(new SqlParameter(PARAM_1, Types.NUMERIC));
declareParameter(new SqlParameter(PARAM_2, Types.NUMERIC));
setFunction(true);
compile();
}
public Map<String, Object> execute(Util util, CustomLogger logger) {
String params = util.EXTRACT_PARAMS;
String arr[] = params.split(",");
logger.writeLine("Extract SP Params are " + arr[0] + ":" + arr[1]);
int firstParam = Integer.parseInt(arr[0]);
int secondParam = Integer.parseInt(arr[1]);
Map<String, Object> inputs = new HashMap<String, Object>();
inputs.put(PARAM_1, firstParam);
inputs.put(PARAM_2, secondParam);
return super.execute(inputs);
}
}
调用存储过程的代码:
public int executeExtractSP() throws Exception {
int returnCode = -1;
try {
Extract extractSP = new Extract(getDataSource(), util.EXTRACT_SP);
long t1 = System.currentTimeMillis();
returnCode = (Integer) extractSP.execute(util, customLogger).get(Constants.STORED_PROC_RETURN_CODE);
long t2 = System.currentTimeMillis() - t1;
customLogger.writeLine("Extract procedure finished running in " + t2 + " milliseconds, return code is " + returnCode);
} catch (Exception ex) {
throw ex;
}
return returnCode;
}
重构前调用存储过程的旧代码:
callStm = con.prepareCall(util.EXTRACT_SP);
callStm.registerOutParameter(1, java.sql.Types.INTEGER);
callStm.setInt(2, firstParam);
callStm.setInt(3, secondParam);
long t1 = System.currentTimeMillis();
boolean flag = callStm.execute();
long t2 = System.currentTimeMillis() - t1;
returnCode = callStm.getInt(1);
logger.writeLine("Extract procedure finished running in " + t2 + " milliseconds, return code is " + returnCode);
以及我收到的内存错误堆栈跟踪:
Thu Dec 17 20:48:56 2015: Extract SP Params are 1:2
Thu Dec 17 21:05:16 2015: java.lang.OutOfMemoryError: Java heap space
at java.lang.String.<init>(String.java:469)
at org.springframework.jdbc.core.JdbcTemplate.extractReturnedResults(JdbcTemplate.java:1193)
at org.springframework.jdbc.core.JdbcTemplate$6.doInCallableStatement(JdbcTemplate.java:1141)
at org.springframework.jdbc.core.JdbcTemplate$6.doInCallableStatement(JdbcTemplate.java:1130)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1078)
at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1130)
at org.springframework.jdbc.object.StoredProcedure.execute(StoredProcedure.java:142)
at com.company.job.storedprocs.Extract.execute(Extract.java:49)
at com.company.job.utils.DBUtil.executeExtractSP(DBUtil.java:456)
at com.company.job.extract.JobExtract.processExtract(JobExtract.java:376)
at com.company.job.Process.main(Process.java:60)
Thu Dec 17 21:05:16 2015: Exiting with code of 8
最佳答案
参数的 SQL 类型为 varchar。我认为这应该是一个 Types.INTEGER。
此外,您还使用 SqlReturnType 将其转换为 Integer。我认为没有必要。
关于java - 为什么我的存储过程仅返回单个整数返回代码,但堆空间不足?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34366092/