关于ORA-01000: maximum open cursors exceeded 在Websphere里

ORA-01000错误解决
本文介绍ORA-01000错误的原因及排查步骤,包括检查数据库参数open_cursors设置、查找占用资源较多的会话,并提供SQL查询帮助定位问题源头。
网上有很多,这边备忘一下。

ORA-01000
这个参数决定一个SESSION的最大打开CURSOR的个数.
可能是异常中断而没有CLOSE,或程序写嘚有问题,或者确实有这么多的CUSOR同时在应用.
 
首先查DB的参数,
       select value
     from v$parameter
     where name = 'open_cursors'
    建议大应用至少1000 .
 
然后,查
           select o.sid, osuser, machine, count(*) num_curs
     from v$open_cursor o, v$session s
     where user_name = 'username' and o.sid=s.sid
     group by o.sid, osuser, machine
     order by num_curs desc;
 
里面肯定有接近 'open_cursors' 的 session , 得到SID.
最后,查看是这些'open_cursors' 都是哪些SQL.
           select q.sql_text
     from v$open_cursor o, v$sql q
     where q.hash_value=o.hash_value and o.sid = XXXXX;
 
现在应该可以定位到那个页面或MODULE导致这个的问题.

Websphere里有个参数Statement cache size ,也是用来缓存的。
看是否大与Oracle的设置。
  • In WebSphere Application Server V5, navigate to the data source in the Admin Console. The Statement cache size appears on the main data source configuration panel.
  • In WebSphere Application Server V6, navigate to the data source in the Admin Console. Under Additional Properties, select WebSphere Application Server data source properties. The first property listed on the resulting screen is the Statement cache size.
另一个也可以设置cursor_sharing = force, 不过这个要看具体环境了。

程序问题,比如:
Java代码在执行conn.createStatement()和conn.prepareStatement()的时候,实际上都是相当与在数据库中 打开了一个cursor。尤其是,如果你的createStatement和prepareStatement是在一个循环里面的话,就会非常容易出现这 个问题。因为游标一直在不停的打开,而且没有关闭。
 
还看到ITPUB上一例是存储空间的问题, 关键还是找到是哪些SQL OPEN 了CURSOR,然后对症下药。
 
为了解决 `ORA-01000: maximum open cursors exceeded` 异常,需要从代码层面和数据库配置两个方面入手。以下是详细的方法和建议: ### 3.1 遵循最佳实践关闭资源 在 Java 应用中,每次调用 `Connection.createStatement()` 或 `Connection.prepareStatement()` 实际上都会在数据库中打开一个游标。如果这些操作位于循环内部或未及时关闭,会导致游标数量迅速增加,从而触发此异常。 因此,应确保以下几点: - **将创建 Statement 和 PreparedStatement 的操作移出循环**,避免重复打开游标。 - **在使用完 ResultSet、Statement 或 PreparedStatement 后立即关闭它们**,即使后续不再使用这些对象,也应在 finally 块中确保关闭,以释放相关资源。 - **使用 try-with-resources(Java 7+)来自动管理资源**,这可以有效防止资源泄漏问题。 ```java try (Connection conn = dataSource.getConnection(); PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM table"); ResultSet rs = pstmt.executeQuery()) { // 处理结果集 } catch (SQLException e) { e.printStackTrace(); } ``` ### 3.2 检查并优化 SQL 查询逻辑 - **减少不必要的查询次数**,尤其是在循环中执行的查询,可以通过批量处理或合并多个查询为单个查询来降低游标的使用频率。 - **尽量避免嵌套查询**,因为它们可能会导致多个游标同时打开,增加资源消耗。 ### 3.3 调整数据库参数(仅作为辅助手段) 虽然不应该依赖调整数据库参数来解决根本问题,但在某些情况下,适当增加 `open_cursors` 的值可能有助于缓解问题,特别是在高并发环境下。 可以通过以下 SQL 查看当前设置: ```sql SHOW PARAMETER open_cursors; ``` 如需修改,可在 Oracle 中通过以下命令进行调整(具体数值应根据实际需求设定): ```sql ALTER SYSTEM SET open_cursors=3000 SCOPE=BOTH; ``` 需要注意的是,这只是“治标不治本”的方法,关键还是要从代码层面解决问题。 ### 3.4 使用连接池时注意游标管理 如果应用使用了连接池(如 HikariCP、C3P0 等),还需要检查连接池的配置,确保每个连接在使用完毕后能够正确归还给池,并且相关的 Statement 和 ResultSet 已经关闭。 ### 3.5 日志监控与调试 - **启用日志记录**,跟踪哪些 SQL 语句频繁打开游标,分析其是否合理。 - **使用数据库视图查看当前打开的游标信息**,例如 `V$OPEN_CURSOR`,帮助识别潜在的问题源。 ```sql SELECT * FROM v$open_cursor WHERE sid = <your_session_id>; ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值