We have developed a huge J2EE application on ORACLE 9iAS (OC4J)for one of our clients. The basic framework uses JSP->Oracle Cleveland Architecture->Stateless Session Beans->DAO->Oracle 9i Database.
Now we had taken ample care to close all the Result Set,Prepared Statements and Connection Objects during coding and have gone through various testing phases. We have been facing this Open Cursor problem for a long time now. Everytime we dig the code and fix the some of it but still there are a lot of open cursors.
With the project progressing to near implementation, we are looking for a solution which can help us resolve this problem. The solution has to be non-invasive and most importantly should not cost us anythin (our budget is long over).
Towards this wanted to know either:
a) If there are any free open source tools which can be used to find out the code files which are keeping the cursors open. OR
b) Can we develop some custom-built tool which can find this out for us. Any pointers on such would be much appreciated. OR
c) If we can get some free tool or built some tool which sits quietly in the App Srvr and closes the open connections for us. Probably by interacting with the container or drivers???
One more constraint we are working with is that we can't take the risk of opening up the code to a large extent as all our testing phases are over.
Any help on any of the above will be much appreicated.
Regards
CZAR.
-
Open Cursors (7 messages)
- Posted by: rohit wazir
- Posted on: April 01 2005 11:36 EST
Threaded Messages (7)
- Open Cursors by Tugdual Grall on April 01 2005 12:04 EST
- Ww also got the same problem and resolved by karamat ali on April 01 2005 12:45 EST
- Ww also got the same problem and resolved by Christopher Stehno on April 01 2005 13:36 EST
- Ww also got the same problem and resolved by Stefan Zobel on April 05 2005 17:35 EDT
-
Ww also got the same problem and resolved by Christopher Stehno on April 05 2005 07:43 EDT
-
Ww also got the same problem and resolved by Stefan Zobel on April 06 2005 05:25 EDT
- thx by rohit wazir on April 09 2005 04:19 EDT
-
Ww also got the same problem and resolved by Stefan Zobel on April 06 2005 05:25 EDT
-
Ww also got the same problem and resolved by Christopher Stehno on April 05 2005 07:43 EDT
-
Open Cursors[ Go to top ]
- Posted by: Tugdual Grall
- Posted on: April 01 2005 12:04 EST
- in response to rohit wazir
Hello Rohit,
Which version of OracleAS/OC4J are you using?(Stand Alone or part of the full OracleAS installation?)
Have your turn on the debug flag for the OC4J Datasource?
Just start your container with the Ddatasource.verbose=true option. e.g: java -Ddatasource.verbose=true -jar oc4j.jar
You can try http://www.p6spy.com/ that is an open source software that wrapp the JDBC Driver/Data Source and give you good feedback on what's happening in your application.
Generic comments/questions..
Are you coding yourself all the access to the DB or you are using EJB, Toplink or other persistence framework?
Regards
Tugdual -
Ww also got the same problem and resolved[ Go to top ]
- Posted by: karamat ali
- Posted on: April 01 2005 12:45 EST
- in response to rohit wazir
The implicit cursors opened by the Oracle are not closed until you close and set the connection to NULL. But if you are using Connection Pooling then Connections are closed after a specific when they are idle or Whatever technique you choose. We are also using connection Pooling and got the same problem but now we have implment a chck in our Pool class when ever we Got connection from Pool we first check either the limit of its cursor is exceeded the maximum limit that is 300 by default in Oracle and if it exceeds then we just close and set to NULL this connection and create a Fresh connection From the DB and put this in our Pool. Below is the snippet of code that we implement, I hope this might be helpful for you.
try
{
String query = "select a.value, b.name from v$mystat a, v$statname b where a.statistic# = b.statistic# and b.name = 'opened cursors current'";
Statement s = con.createStatement();
ResultSet rs = s.executeQuery(query);
rs.next();
long openedCursors = rs.getLong(1);
if(openedCursors > 270)
{
busyConnectionList.removeElement((ConnectionNode)con);
//closing the connect to release oppened cursors
closeDBConnection(con);
//creating new
newConnection = openConnection();
returnNode = new ConnectionNode(newConnection);
busyConnectionList.addConnection(returnNode);
}
rs.close();
rs = null;
s.close();
s=null;
}
catch(java.sql.SQLException ex){
ex.printStackTrace();
throw new ConnectionNodeException(ex.toString());
} -
Ww also got the same problem and resolved[ Go to top ]
- Posted by: Christopher Stehno
- Posted on: April 01 2005 13:36 EST
- in response to karamat ali
I have encounted that problem with Oracle as well... you also want to make sure that you are closing the connections in the finally block not in the try...
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
try {
con = getConnection();
statement = conn.createStatement("...");
rs = statement.executeQuery();
...
} catch(Exception ex){
... handle execption...
} finally {
if(rs != null){
try {rs.close();} catch(Exception ex){}
}
if(statement != null){
try {statement.close();} catch(Exception ex){}
}
if(conn != null){
try {conn.close();} catch(Exception ex){}
}
}
that way they are always closed... this is especially important when the connections are pooled. We found code in our app that did not handle conns this way and it was the source of our cursor problem. -
Ww also got the same problem and resolved[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: April 05 2005 17:35 EDT
- in response to karamat ali
You're kidding right - your suggestion's just an AFD joke?
Otherwise, I'd hope nobody is taking that advice seriously ...
Stefan -
Ww also got the same problem and resolved[ Go to top ]
- Posted by: Christopher Stehno
- Posted on: April 05 2005 19:43 EDT
- in response to Stefan Zobel
If you feel there is something incorrect with the solution, you are free to provide your own or offer a correction... rather than ridiculing the contributions of others. -
Ww also got the same problem and resolved[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: April 06 2005 17:25 EDT
- in response to Christopher Stehno
There's nothing wrong with YOUR solution Christopher. Sorry
if I offended you or anyone else, that was surely not my
intention. Ok, I didn't get the tone right, sorry for that
(had been a very long day).
What I was after, was that incredible... {String query = "select a.value, b.name from v$mystat a, v$statname b where a.statistic# = b.statistic# and b.name = 'opened cursors current'";
Statement s = con.createStatement();
ResultSet rs = s.executeQuery(query);
rs.next();
long openedCursors = rs.getLong(1);
if(openedCursors > 270) ...
There is simply no need for such adventurous code if you
handle your resources like you did (irrespective of using
connection pooling, or not). Also, there's NO reason for
using home-grown connection pools at all.
The only time I have seen behavior like this (despite
correctly closing all resources) was a bug in an older
Oracle 8i JDBC driver that didn't close cursors when they
were "out" parameters in a stored procedure. That was a
long time ago and there existed a better hack for that
particular error.
BTW, I'd suggest that you move your resource cleanup in your
finally clause to a static helper function. That way, you'd
save on code duplication.
Kind regards,
Stefan -
thx[ Go to top ]
- Posted by: rohit wazir
- Posted on: April 09 2005 16:19 EDT
- in response to Stefan Zobel
thx guys but i thought i'd clarify some points here:
a) We have written code to close all the connections objects, RS etc etc in the finally block. Its just that if 100 odd developers work someone's bound to miss that.
b) We are using the full OC4J app server.
c) we have Data access objects managing the interaction with oracle db.
c) there would be close to a 1000 DAOs in the system so any suggestion to scan the code files to rectify the problem would be impossile as well as prone to a lot of errors......
therefore what we are looking at is some component which sits outside the application monitoring the connections and tells us the culprit files...