views:

328

answers:

8

In Java and C#, they both have something like System.terminate(). If my program has open database connections, database readers, and database command variables, and I terminate my program in a catch clause, will database resources still remain in use? or will they be freed automatically since my entire program has just exited?

Normally, how should I handle such cases to make sure I always free database connections, whether through normal program termination or unexpected program termination? Any good practices?

+5  A: 

Unless you specifically close the connection, they will remain open until a timeout hits.

I've found this out the hard way in C# a few times. Best practices dictate to shutdown/close resources you know you will no longer need. File I/O streams , DB connections , etc etc

PSU_Kardi
Is that true even if the application crashes? (Not being facetious, just curious)
Andy White
I would imagine so. I mean, if you have a try/catch and you were in the middle of editing a file and I yank the power cord.Those saves will be lost in limbo....
PSU_Kardi
I think this depends on the type of crash. Certain crashes can affect the runtime (like yanking the power cord, stack overflows, etc.) so in that case, the connection will remain open until it reaches a timeout. If a simple exception is thrown however, I think the runtime will still try to close the connection (if in a 'finally' block)
Dan Herbert
+6  A: 

Upon termination of a process, all associated resources (incl. memory, handles, connections, ...) will be freed up.

Normally, in C#, you'll use the Dispose pattern/using statement to control scarce resources.

Mehrdad Afshari
To the best of my knowledge, I believe you're right. What I find curious is that PSU_Kardi claims the opposite and has more upvotes. So who IS right?
Peter Perháč
@MasterPeter: This is definitely a platform dependent thing. But on most major systems I've seen, this is the case.
Mehrdad Afshari
Upvote ill-ordering corrected.
Tom Anderson
A: 

It should be cleared on the next GC, but to be precise, in C# you can close the connection on finally block of the structured exception handling.

try {
  // open DB connection
} catch (Exception ex) {
  // deal with exception
} finally {
  // close and dispose connection
}
Adrian Godong
Ok. but what if i have db connection statements spread out throughout my program, so that I can't put them together in one try/catch/finally. Should I just put my ENTIRE program in one big try/catch/finally block, so whenever any unexpected error occurs my db will be closed? But putting everything in one big try/catch/finally is not graceful?
Saobi
Errr...where's the GC when the process doesn't exist?
Curt Sampson
Saobi: you should split the DB code into more manageable chunks and put try/catch block on each.Curt: this is BEFORE the process exits, better than just terminating the process because you can't guarantee abnormal termination will always close the connection.
Adrian Godong
A: 

The general POSIX behaviour is that, when the program terminates, all file handles, network connections and so on are closed. Whether the other end does the right thing at that point is an open question, but if you're using any reasonably popular RDBMS, it will be fine.

Curt Sampson
+1  A: 

In C#, implicit cleanup is done by the garbage collector if a finalizer is implemented in the object being garbage collected. Any cleanup of unmanaged resources, such as database connections, can be done in the Dispose method.

See this article for more information:

Implementing Finalize and Dispose to Clean Up Unmanaged Resources
http://msdn.microsoft.com/en-us/library/b1yfkh5e(VS.71).aspx

Robert Harvey
A: 

In C#, you will normally close connections immediately after using them, e.g.:

using(SqlConnection connection = ...)
{
   ... do something ...
} // connection disposed / closed here

However typically you will be using a connection pool, and all this does is returns the connection to the pool. So your process will still have active connections to the database server.

If you shut down cleanly, the connection pool will no doubt be cleaned up, and the actual connections to the database will be closed (you can verify this by looking at the open connections on the database server).

But there are situations (e.g. calling Environment.FailFast) where the application may crash without closing down the connections - in this case they'll eventually time out and be closed by the database server.

Joe
Can you expand on connection pool? And how would I implement them?
Saobi
+1  A: 

When a process terminates, all the file descriptors it has open should be released by the operating system. File descriptors include files and sockets, which will generally cover your database connections.

All that tells you is that when your client terminates its connections are closed. It does not tell you what the server does. Depending on how it is written, it is entirely possible that the server will continue to hold its connections open, expecting messages from the client that will never arrive, or even attempting to send data. These will probably timeout eventually, but this might not be well-planned. (It should be, for a decent RDBMS, but it might not be.) So depending on your RDBMS, you might need to take some steps to tell the server you are going down in order to tell it to release its resources.

skiphoppy
+1  A: 

If you are working with SQL Server you can have a look in sysprocesses or run sp_who2. I tested this on my machine and connections do get closed, i.e:

Console.Write("Opening connection");
Console.ReadLine();
SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=SeniorMail;Integrated Security=SSPI;");
connection.Open();
SqlCommand command = new SqlCommand("SELECT count(*) from Account", connection);
Console.Write("Running sql");
Console.ReadLine();
int? count = command.ExecuteScalar() as int?;
Console.Write("Now I'll throw an exception");
Console.ReadLine();
int a = 0, b = 1, c = 0;

try
{
    c = b / a;
}
catch
{
    Environment.Exit(1);
}

I've checked sp_who2 either side of "Now I'll throw an exception", and I can see the connection has disappeared after the app exits.

russau