首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Oracle阵列的Spring StoredProcedure : ORA-01000:超过了最大打开游标数

使用Oracle阵列的Spring StoredProcedure : ORA-01000:超过了最大打开游标数
EN

Stack Overflow用户
提问于 2016-01-11 15:48:06
回答 2查看 2.6K关注 0票数 8

多次调用带有OracleTypes.ARRAY输入参数的Oracle存储过程时,出现以下错误:-

代码语言:javascript
复制
org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{call EMP_SCHEMA.GET_EMPLOYEE_LIST(?, ?)}]; SQL state [72000]; error code [1000]; ORA-01000: maximum open cursors exceeded; nested exception is java.sql.SQLException: ORA-01000: maximum open cursors exceeded
            at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84) ~[spring-jdbc-4.1.6.RELEASE.jar:4.1.6.RELEASE]
            at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.1.6.RELEASE.jar:4.1.6.RELEASE]

JDBC模板配置为:-

代码语言:javascript
复制
    <bean id="commonsDbcpNativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor" />
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg>
        <ref bean="dataSource" />
    </constructor-arg>
    <property name="nativeJdbcExtractor" ref="commonsDbcpNativeJdbcExtractor" />
</bean>

存储过程类:-

代码语言:javascript
复制
public class GetEmployees extends StoredProcedure {
  public GetEmployees(JdbcTemplate jdbcTemplate) {
    super(jdbcTemplate, "EMP_SCHEMA.GET_EMPLOYEE_LIST");
    declareParameter(new SqlParameter("p_emp_id_list", OracleTypes.ARRAY, "TBL_EMP_ID"));
    declareParameter(new SqlOutParameter(CURSOR, OracleTypes.CURSOR, new EmployeeDataRowMapper()));
    compile();
  }

  public List<Employee> ofIds(Set<EmployeeId> employeeIds) {
    Map<String, OracleArraySqlTypeValue> params = new HashMap<>();
    params.put("p_emp_id_list", new OracleArraySqlTypeValue(employeeIds));
    final Map<String, Object> result = execute(params);

    return (List<Employee>) result.get(CURSOR);
  }
}

Oracle SqlTypeValue :-

代码语言:javascript
复制
public class OracleArraySqlTypeValue extends AbstractSqlTypeValue {
  private final String[][] employeeIds;

  public OracleArraySqlTypeValue(String[][] employeeIds) {
    this.employeeIds = employeeIds;
  }

  @Override
  protected Object createTypeValue(Connection connection, int sqlType, String typeName) throws SQLException {
    ArrayDescriptor arrayDescriptor = new ArrayDescriptor(typeName, connection);
    return new ARRAY(arrayDescriptor, connection, employeeIds);
  }
}

而不是CommonsDbcpNativeJdbcExtractor也尝试了OracleJdbc4NativeJdbcExtractor。但错误仍然存在。

基本上,堆包含许多未关闭的Statement对象。你知道为什么spring没有关闭资源吗?

环境:- Java 1.8,Spring 4.1.6,Tomcat 7。

EN

回答 2

Stack Overflow用户

发布于 2017-07-01 22:34:05

检查您的open_cursor参数。此参数定义每个会话允许的最大游标数。默认值为50。

检查是否有任何游标泄漏。正常情况下,对于普通用户来说,200 ~ 300的值应该足够了。

票数 1
EN

Stack Overflow用户

发布于 2016-01-29 17:01:34

在上述情况下,该问题是由于oracle数组类型的所有权错误造成的。实际上,用户定义的数组类型TBL_EMP_ID属于一个架构,而不是声明存储过程的架构。

通过将数组类型声明移动到声明存储过程GET_EMPLOYEE_LIST的同一架构中,解决了此问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34716456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档