我们的应用程序连接到 Oracle 数据库,我们使用 Spring 提供的 JDBCTemplate 与数据库进行交互。根据 Spring JDBCTemplate 的文档,它确保它将关闭所有连接和游标。但显然我们得到以下打开游标异常。
ORA-01000: maximum open cursors exceeded at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84) ~[spring-jdbc-4.2.6.RELEASE.jar!/:4.2.6.RELEASE] at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.2.6.RELEASE.jar!/:4.2.6.RELEASE] at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.2.6.RELEASE.jar!/:4.2.6.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:645) ~[spring-jdbc-4.2.6.RELEASE.jar!/:4.2.6.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:680) ~[spring-jdbc-4.2.6.RELEASE.jar!/:4.2.6.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:712) ~[spring-jdbc-4.2.6.RELEASE.jar!/:4.2.6.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:722) ~[spring-jdbc-4.2.6.RELEASE.jar!/:4.2.6.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:790) ~[spring-jdbc-4.2.6.RELEASE.jar!/:4.2.6.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:809) ~[spring-jdbc-4.2.6.RELEASE.jar!/:4.2.6.RELEASE]
片段:
private Optional<PartyAccess> executeQuery(Object... args) {
try {
String query = "SELECT EMP.ID as PARTY_ID, EMP.MPIN_HSB, EMP.INVALID_MPIN_HSB_COUNT, " +
"EMP.MPIN_HSB_MODIFIED_ON, EMP.MPIN_LSB, EMP.INVALID_MPIN_LSB_COUNT, EMP.MPIN_LSB_MODIFIED_ON, " +
"EMP.EMP_PIN AS SMS_PIN, EMP.NUMBER_OF_PIN_CODE_FAILURE AS INVALID_SMS_PIN_COUNT, EMP.PIN_MODIFIED_ON, " +
"EMP.PINFLAG AS USE_SHA2_HASH_FOR_PIN, CASE WHEN EMP_BLACKLIST_STATUS = 'Y' THEN 1 ELSE 0 END AS BLOCKED " +
"FROM MTX_EMPLOYEE EMP WHERE EMP.ID = ?";
return Optional.of((PartyAccess) jdbcTemplate.queryForObject(query,
args,
new BeanPropertyRowMapper(PartyAccess.class)));
} catch (DataAccessException ex) {
LOGGER.error("Error occurred", ex);
return Optional.empty();
}
}
我们将 hikari 用于 JDBC 连接池,最大大小为 10。当应用程序收到大量请求时,我们会遇到这个问题。我尝试增加数据库的 max_cursors(我知道这是个糟糕的解决方案)。但即便如此,这也无济于事。当有大量请求进入时,我们监控打开的游标,该值没有超过正在设置的最大游标值。
最佳答案
将 JPA 版本升级到最新版本后,问题得到解决。较早的 spring jpa 版本未正确关闭游标。
关于Spring JDBC 模板 - 超出最大打开游标数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39389087/