<commit_before>---
layout: post
title: PreparedStatement导致ORA-01000
categories: jdbc
description: PreparedStatement操作导致游标超限ORA-01000
keywords: jdbc, java
---

维护一个老项目时发现一个业务异常，对应的数据库业务异常堆栈信息为 ORA-01000，初步判断是PreparedStatement使用不规范导致。

# 调试跟进

经过分析，业务代码执行过程中在大约310次 PreparedStatement 操作时出现异常，对应的正好是Oracle的默认游标数量设置300:

`show parameter open_cursors;`

但是跟进到业务代码中发现并非是预料的for循环中不断创建新的ps实例，而是如下形式：

	ps = conn.prepareStatement(sql);
    for (int i = 0; i < list.size(); i++) {
		ps.set(1,xxx);
		...;
	}
	ps.close();

经分析是中间的循环次数比较多，导致：

`java.sql.SQLException: ORA-01000: 超出打开游标的最大数`

和预料的不太一样。查资料整理如下：

- 没有使用数据库连接池情况下，close Connection的时候已经把数据库资源完全释放掉了，PreparedStatement占用的数据库游标也会随即释放；但是大部分项目会使用连接池技术，close Connection就不是简单的直接中断物理连接了，而是返还connection给连接池，在这种情况下，close了Connection，但是PreparedStatement并没有被释放掉，占用的数据库游标仍然处于打开状态。

- 单个 PreparedStatement 重复进行操作而不关闭，相当于在数据库里也是打开了多个游标，同样会导致 ORA-01000

附注：

### 修改oracle 最大游标数为 1000

`alter system set open_cursors=1000 scope=both;`

环境 Oracle11G R2<commit_msg>2016年10月27日20:02:37<commit_after>---
layout: post
title: PreparedStatement导致ORA-01000
categories: Jdbc
description: PreparedStatement操作导致游标超限ORA-01000
keywords: jdbc, java
---

维护一个老项目时发现一个业务异常，对应的数据库业务异常堆栈信息为 ORA-01000，初步判断是PreparedStatement使用不规范导致。

# 调试跟进

经过分析，业务代码执行过程中在大约310次 PreparedStatement 操作时出现异常，对应的正好是Oracle的默认游标数量设置300:

`show parameter open_cursors;`

但是跟进到业务代码中发现并非是预料的for循环中不断创建新的ps实例，而是如下形式：

	ps = conn.prepareStatement(sql);
    for (int i = 0; i < list.size(); i++) {
		ps.set(1,xxx);
		...;
	}
	ps.close();

经分析是中间的循环次数比较多，导致：

`java.sql.SQLException: ORA-01000: 超出打开游标的最大数`

和预料的不太一样。查资料整理如下：

- 没有使用数据库连接池情况下，close Connection的时候已经把数据库资源完全释放掉了，PreparedStatement占用的数据库游标也会随即释放；但是大部分项目会使用连接池技术，close Connection就不是简单的直接中断物理连接了，而是返还connection给连接池，在这种情况下，close了Connection，但是PreparedStatement并没有被释放掉，占用的数据库游标仍然处于打开状态。

- 单个 PreparedStatement 重复进行操作而不关闭，相当于在数据库里也是打开了多个游标，同样会导致 ORA-01000

附注：

### 修改oracle 最大游标数为 1000

`alter system set open_cursors=1000 scope=both;`

环境 Oracle11G R2
{'fraction_non_alphanumeric': 0.09719438877755511, 'fraction_numerical': 0.05110220440881764, 'mean_word_length': 7.645021645021645, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1062079', 'n_tokens_mistral': 1233, 'n_tokens_neox': 1378, 'n_words': 113}