MSDN Documentation

ADO.NET Transactions

Transactions are a fundamental concept in database management, ensuring data integrity by allowing a series of operations to be treated as a single, atomic unit. If any part of the transaction fails, the entire transaction is rolled back, leaving the database in its original state. ADO.NET provides robust support for managing database transactions through its transaction objects.

Understanding Database Transactions

A database transaction adheres to the ACID properties:

In ADO.NET, transactions are managed using the DbTransaction class and its provider-specific implementations (e.g., SqlTransaction for SQL Server).

Managing Transactions with ADO.NET

The process of managing a transaction typically involves the following steps:

  1. Open a connection: Establish a connection to the database.
  2. Begin the transaction: Call the BeginTransaction() method on the connection object. This returns a transaction object.
  3. Execute commands: Associate DbCommand objects with the transaction. This ensures that commands are executed as part of the transaction.
  4. Commit or Rollback:
    • If all operations are successful, call the Commit() method on the transaction object.
    • If an error occurs, call the Rollback() method on the transaction object.
  5. Close the connection: Release the database connection.
Important: Always ensure that you call either Commit() or Rollback() within a finally block or use a using statement to guarantee transaction disposal and prevent resource leaks.

Example: Using a Transaction with SQL Server

The following C# code demonstrates how to use a SqlTransaction to perform a series of database operations:


using System;
using System.Data.SqlClient;

public class TransactionExample
{
    public static void Main(string[] args)
    {
        string connectionString = "Server=myServerAddress;Database=myDataBase;User ID=myUsername;Password=myPassword;";

        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            SqlTransaction transaction = null;

            try
            {
                // Begin the transaction
                transaction = connection.BeginTransaction();

                // Create commands and associate them with the transaction
                SqlCommand command1 = new SqlCommand("UPDATE Accounts SET Balance = Balance - 100 WHERE AccountId = 1", connection, transaction);
                command1.ExecuteNonQuery();

                SqlCommand command2 = new SqlCommand("UPDATE Accounts SET Balance = Balance + 100 WHERE AccountId = 2", connection, transaction);
                command2.ExecuteNonQuery();

                // If both commands succeed, commit the transaction
                transaction.Commit();
                Console.WriteLine("Transaction committed successfully.");
            }
            catch (Exception ex)
            {
                // If an error occurs, roll back the transaction
                if (transaction != null)
                {
                    transaction.Rollback();
                    Console.WriteLine("Transaction rolled back. Error: " + ex.Message);
                }
            }
            finally
            {
                // Ensure connection is closed
                if (connection.State == System.Data.ConnectionState.Open)
                {
                    connection.Close();
                }
            }
        }
    }
}
            

Transaction Isolation Levels

ADO.NET allows you to specify the isolation level for your transactions. The isolation level determines the degree to which one transaction must be isolated from the data modifications made by other concurrent transactions. Common isolation levels include:

You can specify the isolation level when calling BeginTransaction():


SqlTransaction transaction = connection.BeginTransaction(System.Data.IsolationLevel.RepeatableRead);
            

Key Classes and Methods

DbConnection (and provider-specific classes like SqlConnection)

DbTransaction (and provider-specific classes like SqlTransaction)

DbCommand (and provider-specific classes like SqlCommand)

Best Practices