开发者社区> 问答> 正文

druid1.2.6+ojdbc19.14.0.0循环执行同一条sql报java.sql.SQLEx

测试用例: `@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

展开
收起
山海行 2023-07-05 17:59:57 94 0
3 条回答
写回答
取消 提交回答
  • 北京阿里云ACE会长

    在使用 Druid 1.2.6 和 ojdbc8 19.14.0.0 时,循环执行同一条 SQL 语句可能会导致 java.sql.SQLException: ORA-01000: maximum open cursors exceeded 异常。

    这个异常表示打开的游标数量超过了数据库的最大限制。在 Oracle 数据库中,默认情况下,每个会话最多可以打开 1000 个游标,如果超过了这个限制,就会抛出这个异常。

    2023-07-30 20:57:03
    赞同 展开评论 打赏
  • initialSize:连接池的初始大小。
    maxActive:连接池的最大活动连接数。
    maxIdle:连接池的最大空闲连接数。
    maxWait:连接池中等待连接的最大时间。
    minIdle:连接池的最小空闲连接数。
    testOnBorrow:当从连接池中获取连接时,是否进行连接的验证。
    testWhileIdle:当空闲连接超过多长时间时,是否进行连接的验证。
    timeBetweenEvictionRunsMillis:连接池中空闲连接的最长空闲时间。
    minEvictableIdleTimeMillis:连接池中空闲连接的最小空闲时间。
    validationQuery:连接池验证连接的SQL语句。
    defaultAutoCommit:连接的默认自动提交设置。
    
    2023-07-09 10:18:30
    赞同 展开评论 打赏
  • 你分析的对,缓存的pstmt,导致之前的已经关闭了。

    原回答者GitHub用户kimmking

    2023-07-06 10:38:09
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
SQL Server 2017 立即下载
GeoMesa on Spark SQL 立即下载
原生SQL on Hadoop引擎- Apache HAWQ 2.x最新技术解密malili 立即下载