We are stuck in a situation where one of our processes is taking 3 hours of computing without touching the database. The connection that was taken before calling the process gets closed by the Oracle server and any subsequent query or commit throws connection closed exception.
It appears to us that the problem is related to Oracle closing the connection that is idle for that long for some reason.
We tried changing EXPIRE_TIMEOUT in sqlnet.ora but that didn't help either.
What can we do to resolve this problem?
What is the error you get when you try to use the connection?
Oracle by default will not close a connection due to inactivity. You can configure a profile with an IDLE_TIME to cause Oracle to close inactive connections, but it doesn't sound like you've done that. You can also configure Oracle to detect dead connections and close the connection if the client doesn't respond-- if the client is buried for three hours, it's possible that it's not responding in a timely fashion. But that seems less likely ad requires additional configuration steps.
The more likely situation in my experience is that your network is dropping the connection. If you are connecting via a firewall, for example, the firewall will frequently close connections that have been idle too long.
The actual Oracle error message you are receiving will indicate which of these alternatives is causing your problem.
Irfan,
Please make sure you have the resource_limit=TRUE in the init.ora file for the changes to take effect.
Also, please check if the user you are trying to set the limit for is assigned to the default profile.
select profile from dba_users where username = 'TEST_USER';
PROFILE1
select profile, resource_name, limit
from dba_profiles where
profile='PROFILE1' and
resource_name ='IDLE_TIME'
3 If the user is asigned to a custom profile make sure the parameters for the custom profile are set acordingly. You should also look at the connect_time parameter (in the default or the custom profile whichever applies to you. Once the connection time is exceeded, the connection is terminated . )
And finally, please note that if the current session started before the parameter was set, it will not be taken into effect. The changes kick-in only from the next session after you make the changes.
Useful links.
http://www.adp-gmbh.ch/blog/2005/april/17.html
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:453256655431
Thanks,
Rajesh
No matter what database you're using it's a bad idea to assume your connection is going to be live when you want to use it. One way to handle this is to create a function to return an active connection to the database in question, and to call it every time you need a handle/object/whatever for a given database. The routine maintains a list of databases and their associated connection object. If the connection object is live when the function is called all's well and good and the object is returned after the function does something with it to convince the database to keep the handle/object/whatever open. If there's no live connection object the routine opens a new one and returns that. It's useful to have a second routine that camps out on a timer that expires after 1 minute or so. When the timer expires and the second routine is called it looks through the list of database connections, looking for ones with no activity for a set amount of time (something significantly less that the database's session timeout value). Those that have been inactive for too long get closed and cleaned up.
It seems actual reason for the connection closed exception
is same as what @Justin Cave mentioned in his answer:
The more likely situation in my experience is that your network is
dropping the connection. If you are connecting via a firewall, for
example, the firewall will frequently close connections that have been
idle too long.
The actual Oracle error message you are receiving will indicate which
of these alternatives is causing your problem.
If still someone want to know the IDLE_TIME
and CONNECT_TIME
configured for a profile, then one can execute below query:
select * from user_resource_limits user_resource where user_resource.resource_name in ('IDLE_TIME','CONNECT_TIME');