Troubleshooting Open Cursor Issues

白昼怎懂夜的黑 提交于 2020-02-28 15:48:13

25 Troubleshooting Open Cursor Issues

Similar to any application that uses Oracle Database as backend repository, Oracle Identity Manager runs several SQL statements. For every SQL statement execution in Oracle Database, certain area in the memory is allocated. Oracle PL/SQL allows you to name this area. This private SQL area is called context area or cursor. These cursors take up space in the shared pool, which is essential memory component of Oracle Database, specifically in the library cache. To keep a renegade session from filling up the library cache or clogging the CPU with millions of parse requests, the OPEN_CURSORS database parameter must be set to limit the cursors.

The OPEN_CURSORS parameter sets the maximum number of cursors that each session can have open, per session. For example, if the value of OPEN_CURSORS is set to 1000, then each session can have up to 1000 cursors open at one time.

Sometimes, the number of cursors in the database exceeds the maximum limit, and as a result, the following error is thrown:

java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-01000: maximum open cursors exceeded ORA-00604: error occurred at recursive SQL level 1

To troubleshoot the open cursors issue:

  1. Login to the SYS schema (or any schema with DBA privilege) of the database.

  2. Find out the session that is causing the error by using the following SQL statement:

    select a.value, s.username, s.sid, s.serial# from v$sesstat a, v$statname b, v$session s where a.statistic# = b.statistic#  and s.sid=a.sid and b.name = 'opened cursors current' and s.username is not null;

    The output displays the details of all sessions. You can see the maxed out session IDs.

  3. To display which queries are causing maxing out of open cursors, run the following SQL statement:

    select  sid ,sql_text, count(*) as "OPEN CURSORS", USER_NAME from v$open_cursor where sid in ($SID);

    The top queries that are opening maximum cursors and are not closing subsequent cursors gracefully are displayed.

    If some code is running above SQL queries, then check that Java Statement, Resultset, or connection are closing properly or not if they have access to the code. If the code is not closing the connections, then close all the open connections properly so that you can save memory leaks in the code and save database memory.

  4. To verify if you have set the value of the OPEN_CURSORS parameter high enough, monitor v$sesstat for the maximum opened cursors current, as shown:

    SELECT  max(a.value) as highest_open_cur, p.value as max_open_cur FROM v$sesstat a, v$statname b, v$parameter p WHERE  a.statistic# = b.statistic#  and b.name = 'opened cursors current' and p.name= 'open_cursors' group by p.value;

    If your sessions are running close to the limit, then increase the value of the OPEN_CURSORS parameter.

 问题原因分析:



import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Insertwork {
	public static void main(String[] args) {

		PreparedStatement psbatchinsert = null;	
		Connection connection = getOracleConnection();
		try {
			connection.setAutoCommit(false);
			String insertsql = "insert XXXX"
		} catch (SQLException e1) {

			e1.printStackTrace();
		}
		int k=0;//for autocommit
		
		for (int i = 100; i < 20100; i++) {		
            Connection connection = getOracleConnection();	###问题代码一
            psbatchinsert=connection.prepareStatement(insertsql);###问题代码二
            int j=i+1000;
			try {
				psbatchinsert.setInt(1,j);
				psbatchinsert.setString(2, loginname);
				psbatchinsert.addBatch();
				if(k==1000){
				psbatchinsert.executeBatch();
				connection.commit();
				k=0;
				}
				k++;
				
			} catch (SQLException e) {
				
				try {
					connection.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				}

				e.printStackTrace();
			}
			
		}//finally commit
		try {
			psbatchinsert.executeBatch();
			connection.commit();
			connection.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		System.out.println("####insert success################");
	

	}

	public static Connection getOracleConnection() {

		Connection conn = null;

		try {

			Class.forName("oracle.jdbc.driver.OracleDriver");

			conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1533:test73db", "amc", "amc00");

		} catch (Throwable e) {

			e.printStackTrace();

		}
		return conn;

	}

}

仔细分析一下上面的代码发现有两个问题

Connection connection = getOracleConnection();	###问题代码一
psbatchinsert=connection.prepareStatement(insertsql);###问题代码二

因为把这两个语句放在循环里面了,问题一导致

java.sql.SQLRecoverableException: IO Error: Got minus one from a read call

问题二导致

java.sql.SQLException: - ORA-01000: maximum open cursors exceeded 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!