测试用例: `@Test public void testQuery() throws SQLException, InterruptedException { DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName("oracle.jdbc.driver.OracleDriver"); ds.setUrl("jdbc:oracle:thin:@127.0.0.1:1521/orcl"); ds.setUsername("test"); ds.setPassword("test");
ds.setDriverClassLoader(ClassLoader.getSystemClassLoader()); ds.setInitialSize(5); ds.setMaxActive(30); ds.setMinIdle(5); ds.setMaxWait(5000); ds.setTimeBetweenEvictionRunsMillis(120000); ds.setMinEvictableIdleTimeMillis(300000); ds.setTestWhileIdle(true); ds.setTestOnBorrow(false); ds.setPoolPreparedStatements(true); ds.setMaxPoolPreparedStatementPerConnectionSize(20); ds.setValidationQuery("select sysdate from dual"); ds.setDefaultAutoCommit(true);
while (true) { DruidPooledConnection connection = null; boolean originalAutoCommit = false; try { connection = ds.getConnection(); originalAutoCommit = connection.getAutoCommit(); connection.setAutoCommit(false); String sql = "SELECT lock_key,lock_value,expire FROM distributed_lock WHERE lock_key = ? FOR UPDATE"; try (PreparedStatement pst = connection.prepareStatement(sql)) { pst.setString(1, "AsyncCommitting"); ResultSet resultSet = pst.executeQuery(); if (resultSet.next()) { DistributedLockDO distributedLock = new DistributedLockDO(); distributedLock.setExpireTime(resultSet.getLong(ServerTableColumnsName.DISTRIBUTED_LOCK_EXPIRE)); distributedLock.setLockValue(resultSet.getString(ServerTableColumnsName.DISTRIBUTED_LOCK_VALUE)); distributedLock.setLockKey("AsyncCommitting"); System.out.println(distributedLock); } } connection.commit(); } catch (Exception e) { LOGGER.error("execute acquire lock failure, key is: {}", "AsyncCommitting", e); try { if (connection != null) { connection.rollback(); } } catch (SQLException ex) { LOGGER.warn("rollback fail because of {}", ex.getMessage(), ex); } } finally { try { if (originalAutoCommit) { connection.setAutoCommit(true); } IOUtil.close(connection); } catch (SQLException ignore) { } }
Thread.sleep(1000);
}
}` 报错: java.sql.SQLException: 关闭的语句 at oracle.jdbc.driver.OracleClosedStatement.exitImplicitCacheToActive(OracleClosedStatement.java:2957) at oracle.jdbc.driver.OraclePreparedStatementWrapper.exitImplicitCacheToActive(OraclePreparedStatementWrapper.java:1249) at com.alibaba.druid.util.OracleUtils.exitImplicitCacheToActive(OracleUtils.java:94) at com.alibaba.druid.pool.PreparedStatementPool.get(PreparedStatementPool.java:66) at com.alibaba.druid.pool.DruidPooledConnection.prepareStatement(DruidPooledConnection.java:361)
给数据源配置useOracleImplicitCache为false是可以跳过statement的缓存的,但是不知道这个参数有没有什么其他影响,文档里也没找到。
原提问者GitHub用户sixlei
在使用 Druid 1.2.6 和 ojdbc8 19.14.0.0 时,循环执行同一条 SQL 语句可能会导致 java.sql.SQLException: ORA-01000: maximum open cursors exceeded 异常。
这个异常表示打开的游标数量超过了数据库的最大限制。在 Oracle 数据库中,默认情况下,每个会话最多可以打开 1000 个游标,如果超过了这个限制,就会抛出这个异常。
initialSize:连接池的初始大小。
maxActive:连接池的最大活动连接数。
maxIdle:连接池的最大空闲连接数。
maxWait:连接池中等待连接的最大时间。
minIdle:连接池的最小空闲连接数。
testOnBorrow:当从连接池中获取连接时,是否进行连接的验证。
testWhileIdle:当空闲连接超过多长时间时,是否进行连接的验证。
timeBetweenEvictionRunsMillis:连接池中空闲连接的最长空闲时间。
minEvictableIdleTimeMillis:连接池中空闲连接的最小空闲时间。
validationQuery:连接池验证连接的SQL语句。
defaultAutoCommit:连接的默认自动提交设置。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。