C# – Problem with Rolling back a linq2sql insert transaction in C#

clinq-to-sqlrollbacksqltransactions

i am trying to insert the contents of a CSV file into a database table using linq2SQL.

I want to be able to rollback the transaction if ANY of the inserts fail but when i try with this code i get the following error at – db.Transaction.Commit()

System.InvalidOperationException was unhandled: This SqlTransaction has completed; it is no longer usable.

Does anyone know what i am doing wrong?

using (DataContext db = new DataContext())
{
    db.Connection.Open();
    db.Transaction = db.Connection.BeginTransaction();

    try
    {
        foreach (string entry in entries)
        {
            XXX xxx = new XXX()
            {
                P1 = "something",
                P2 = "something"
            };

            db.XXXX.InsertOnSubmit(xxx);
            db.SubmitChanges();
        }
    }
    catch (Exception)
    {
        db.Transaction.Rollback();
    }
    finally
    {
        db.Connection.Close();
    }

    db.Transaction.Commit();
}

Best Answer

Well, the ordering is wrong - you are calling db.Transaction.Commit() after the whole big block, so it'll be called even when an exception occured and you already called db.Transaction.Rollback();

Change your code to:

using (DataContext db = new DataContext())
{
    db.Connection.Open();
    db.Transaction = db.Connection.BeginTransaction();

    try
    {
        foreach (string entry in entries)
        {
            ....
            db.XXXX.InsertOnSubmit(xxx);
            db.SubmitChanges();
        }

        db.Transaction.Commit(); <== CALL HERE !!
    }
    catch (Exception)
    {
        db.Transaction.Rollback();
    }
    finally
    {
        db.Connection.Close();
    }
}

In this case, your Commit is called after the foreach, but it will NOT be called if you run into an exception and do a rollback.

Marc

Related Topic