2017-07-06 224 views
1

我有一个关于性能的问题。CallableStatement.close()会导致性能问题

我工作的应用程序是一个Spring MVC应用程序(v3.2.9)。它托管在WebSphere Application Server(v8.5.5)上。它连接到AS400 DB2系统(驱动程序是JTOpen v9.1)。我的应用程序在IBM AS400系统上调用存储过程。它被称为使用Spring的JdbcTemplate.execute方法。下面的代码:

jdbcTemplate.execute(new CallableStatementCreator() { 
     @Override 
     public CallableStatement createCallableStatement(Connection con) throws SQLException { 
      CallableStatement cs = con.prepareCall("{CALL XXXXXXSP (?, ?)}"); 
      cs.setString(1, xxx); 
      cs.setString(2, xxx); 
      return cs; 
     } 
    }, 
    new CallableStatementCallback<String>() { 
     @Override 
     public String doInCallableStatement(CallableStatement cs)throws SQLException, DataAccessException { 
      cs.execute(); 
      return null; 
     } 
    }); 

我们遇到了一些问题,其中该过程的调用偶尔会引发错误“[SQL0501]光标C1不开”调高记录和审查后,它看起来像这样的错误只有在应用程序尝试重新使用CallableStatement时才会发生。相应的游标在上次使用此CallableStatement时被关闭,导致错误(我不是100%确定是否这种重用是预期的行为)。错误发生在每天20次左右,这是一个相对较低的百分比,因为这个应用程序有更高的流量。

我的问题是,将cs.execute();之后的代码加入cs.close();会导致代码性能下降吗?

+0

问题出在您要在AS400上调用的程序中。你将不得不在AS400上修复它。我在野外看到这些信息时,如果没有找到记录,就不会执行close语句,也不会执行承诺控制的初始提交。我也在野外看到没有检查打开是否成功,因此抓取失败。添加代码以检查打开的语句。如果公开失败,则发布另一个公开声明。 – danny117

+0

@ danny117感谢您的建议,只是想澄清...您所指的开放语句和关闭语句将在AS400上的程序中,而不是在Java代码中,是正确的吗? –

+0

是的,它看起来像as400编码问题。我假设close是关闭游标。 – danny117

回答

2

一般来说,您应该调用close()方法来关闭语句,因为它释放资源。这没有任何问题。

但是JdbcTemplate关闭语句适合你,所以不需要它。

这里是JdbcTemplate的做在执行结束execute(CallableStatementCreator csc, CallableStatementCallback<T> action)方法:

JdbcUtils.closeStatement(cs); 
DataSourceUtils.releaseConnection(con, getDataSource()); 

而且从CallableStatementCallback API:

doInCallableStatement(CallableStatement cs) throws SQLException ,DataAccessException 

获取由JdbcTemplate.execute调用的活动JDBC 的CallableStatement 。不需要关心关闭语句 或连接,或关于处理事务:这将全部是由Spring的JdbcTemplate处理的 。 注意:任何ResultSets打开应该 在回调实现中的最后块中关闭。 Spring 将在返回回调后关闭Statement对象,但是此 不一定意味着ResultSet资源将为 已关闭:Statement对象可能会被连接池合并, 只有关闭调用才会将对象返回到池但不是 物理关闭资源。

+0

看起来像存储过程显式打开的任何结果集需要由客户端关闭。我不确定应该发生的框架在哪里。如果结果集不应该返回给调用者,那么存储过程应该已经关闭了结果集。另外,由于游标名称在作业中必须是唯一的,所以存储过程对于游标名称应该使用比C1更具体的名称。 – jweberhard

相关问题