java - 为什么我的存储过程仅返回单个整数返回代码,但堆空间不足?

标签 java spring stored-procedures jdbc jdbctemplate

我正在使用 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/

相关文章:

oracle - 事务上下文中 Oracle 存储过程/函数的语义

sql-server - 从存储过程插入不同的列

java - 使用 selenium 库在本地替换网站上的图像

java - 如何在 Java 的 AWS lambda 处理程序中请求 http 方法?

java - java.time 的 Spring DateTimeFormat 配置

java - REST Spring Java 中 ResponseEntity<> 的返回类型和简单对象(例如用户)之间有什么区别?

java - 为什么我的 Spring Boot Controller 不自动连接 validator ?

django - 将存储过程加载到 Django 单元测试数据库中的最佳方法是什么?

Java 8流 "Cannot use this in a static context"

java - 如何通过单击按钮打开一个新的 JPanel 窗口?