views:

12

answers:

1

I did a simple test to understand how transactions work in .net

Sample code on which my transaction test was done is

_sqlHelper = new SqlHelper(true);
try
{
    _sqlHelper.ExecuteNonQuery(SpName.sp_UpdateRoomStatus.ToString()
        , Parameters.SqlParam<int?>("DepartmentId", this.DepartmentId, SqlDbType.Int)
        );

    _sqlHelper.ExecuteNonQuery(SpName.sp_UpdateRoomStatus.ToString()
        , Parameters.SqlParam<int?>("DepartmentId", this.DepartmentId, SqlDbType.Int)
        );

    _sqlHelper.CommitTransaction();
}
catch (SqlHelperException ex)
{
    _sqlHelper.RollBackTransaction();
}

Description about the test

When I writes new SqlHelper(true); a new transaction starts internally and connection has been created and opened to database.

_sqlHelper.ExecuteNonQuery(SpName.sp_UpdateRoomStatus.ToString()
    , Parameters.SqlParam<int?>("DepartmentId", this.DepartmentId, SqlDbType.Int)
    );

Now above function executes my procedure and do changes in a database.

I wrote same function call twice to execute procedure two times. This procedure do insertion in database. This procedure contains 3 insert queries in 3 different tables. Now I marked breakpoint on both function calls.

As soon as control comes on 1st breakpoint I simply lets its processing do which means 1st procedure has done insertion.

Now I unplugged my LAN wire since DB was on remote system. Which means connection lost. Hence transaction to be rolledback.

Now When I verified database after the whole process completed. I found data to be in consistent state hence proving that transaction is working.

I am confused at this moment that where did an actual insertion took place from 1st procedure call, since procedure executed successfully. How sql server get notified that transaction was going on and rollback has to be taken place.

It seems as if connection was established to database notifying that connection contains transaction and should get rolled back if connection gets lost.

Hence also stating that Changes made are maintained at Database rather than .net environment.

+1  A: 

The database knows that the connection and the changes should be in a transaction - the actual changes and original data are stored in the database transaction log. When the transaction isn't properly committed and the connection is lost, the database automatically rolls back the transaction.

Basically, in SqlTransactions (not distributed) .Net does nothing clever, it is all handled by the database.

ck
But How do a Database knows that more queries are still in a queue to be executed. And all queries are atomic. Does a connection to database is always considered as a single transaction ?
Shantanu Gupta
It doesn't know that there are any more, it just knows that the COMMIT command hasn't been called, so anything since the start of the transaction should be rolled back.
ck
But who is calling Commit Command. No one notified Database when the transaction started and when it gets commited unless we specify Transaction explicitly every query is considered as an individual transaction so how come database come to know that complete batch has to be considered a single transaction. Hence call commit
Shantanu Gupta
Your question states the SqlHelper starts a transaction (when a transaction is started, the database is notified), and your code listing explicitly calls Commit before the end of the `try` section.
ck
@ck: does this means that whenever a connection to database is created .net will notify DB that current connection is under a transaction. Hence some technique exists in sql server to create a transaction specific connections as well.
Shantanu Gupta
No, there has to be code called that initiates a Transaction, unless the database option `EXPLICIT_TRANSACTION` is set to `ON`.
ck
@ck: Thanks this is what I was looking at
Shantanu Gupta