IulianT
IulianT

Reputation: 410

objects in the try catch block

Take this code sample:

string status = "ok";
SqlCommand cmd=null;
SqlTransaction trans=null;
try
{
    cmd = defs.prepquery("");
    trans = cmd.Connection.BeginTransaction();
    cmd.Transaction = trans;

}
catch (Exception ex)
{
    status = defs.logerror("initalizing sql transaction:" + ex.ToString());
    return status;
}

try
{
    if (oper == "submit")
    {
        cmd.CommandText = "update DCM_Mapping_Sessions set StatusID=2 " + 
            "where MappingSessionID=" + mpsid + "";
        cmd.ExecuteNonQuery();
    }
    else if (oper == "delete")
    {
        // .......etc etc 
    }
    catch(Exception ex2)
    {
        //rollback , close the connection
       // handle the ex 
    }

    // if everything is ok , comit the transaction and close the connection
}

So my question is: What happens with the objects in the try block when an exception occurs ? Does C# allows me to be lazy and destroys the objects(destroying the pending transaction meaning rollback) and closes the connection if an exception occurs ?

I come from a C\C++ background so i am doing my stuff as above to be safe and not end with a transaction open if an exception occurs somewhere below.

Upvotes: 1

Views: 1088

Answers (3)

Jodrell
Jodrell

Reputation: 35696

Short answer, no.

Longer answer, yes but far too late.

This is why we have the finally clause and the using block. You are responsible for calling the close or dispose.

They will get closed or disposed later when the garbage collector is forced to do this "slowly" for you but, there will be an indeterminate period where your expensive resources are wasted unesscessarily.

Something like this would be preferable

using(var connection = defs.GetConnection())
using(var cmd = new SqlCommand())
{
    cmd.Connection = connection;
    switch(oper)
    {
        case "submit":
             cmd.CommandText = "update DCM_Mapping_Sessions" +
                               "set StatusID=2" +
                               "where MappingSessionID=" + mpsid;
        case "...
    }

    try
    {
        cmd.ExecuteNonQuery();
    }
    catch(SomeSpecificExceptionIShouldActuallyHandleHere ex)
    {
       ...
    }
}

Possible injection attack aside.

Upvotes: 0

Oded
Oded

Reputation: 498904

You should be disposing/closing the connection and transaction.

The best way to do so is to wrap the creation in a using statement.

Provides a convenient syntax that ensures the correct use of IDisposable objects.

In essence a using statement wraps the creation of the objects in try{}finally{} blocks to ensure proper disposal.

    using(var cmd = defs.prepquery(""))
    using(var trans = cmd.Connection.BeginTransaction())
    {

    }

Upvotes: 4

Martin Hennings
Martin Hennings

Reputation: 16846

Have a look at try-finally.

It does exactly what you're asking for.

So your code looks like:

try
{
   //try something
}
catch(Exception ex2)
{
   // handle the ex 
}
finally
{
    //rollback , close the connection
}

Upvotes: 5

Related Questions