Compartir a través de


Transacciones locales (ADO.NET)

Las transacciones de ADO.NET se utilizan cuando se desea enlazar varias tareas para que se ejecuten como una sola unidad de trabajo. Por ejemplo, imagine que una aplicación realiza dos tareas. Primero, actualiza una tabla con información de pedidos. Luego, actualiza una tabla que contiene la información de inventario, cargando en cuenta los elementos pedidos. Si alguna de las tareas da error, ambas actualizaciones se revierten.

Determinación del tipo de transacción

Una transacción se considera local cuando consta de una única fase y es controlada directamente por la base de datos. Las transacciones se consideran distribuidas cuando se coordinan mediante un monitor de transacciones y utilizan mecanismos a prueba de errores (como confirmación en dos fases) en la resolución de transacciones.

Cada proveedor de datos de .NET Framework tiene su propio objeto Transaction para realizar transacciones locales. Si necesita que se realice una transacción en una base de datos de SQL Server, seleccione una transacción de System.Data.SqlClient. En transacciones de Oracle, utilice el proveedor System.Data.OracleClient. Además, existe una nueva clase DbTransaction disponible para la escritura de código independiente del proveedor que requiere transacciones.

NotaNota

Las transacciones son más eficientes cuando se realizan en el servidor.Si trabaja con una base de datos de SQL Server que hace uso masivo de transacciones explícitas, debería estudiar la posibilidad de escribirlas como procedimientos almacenados mediante la instrucción BEGIN TRANSACTION de Transact-SQL.Para obtener más información acerca de la realización de transacciones de servidor, vea los Libros en pantalla de SQL Server.

Realización de una transacción mediante una única conexión

En ADO.NET, las transacciones se controlan con el objeto Connection. Puede iniciar una transacción local con el método BeginTransaction. Una vez iniciada una transacción, puede inscribir un comando en esa transacción con la propiedad Transaction de un objeto Command. Luego, puede confirmar o revertir las modificaciones realizadas en el origen de datos según el resultado correcto o incorrecto de los componentes de la transacción.

NotaNota

El método EnlistDistributedTransaction no se debe emplear en transacciones locales.

El ámbito de la transacción está limitado a la conexión. En el siguiente ejemplo se realiza una transacción explícita que consta de por dos comandos independientes en el bloque try. Los comandos ejecutan instrucciones INSERT con respecto a la tabla Production.ScrapReason de la base de datos de ejemplo AdventureWorks de SQL Server 2005, que se confirman si no se produce ninguna excepción. El código del bloque catch revierte la transacción si se produce una excepción. Si la transacción se anula o la conexión se cierra antes de que se haya completado la transacción, ésta se revierte automáticamente.

Ejemplo

Para llevar a cabo una transacción, siga estos pasos.

  1. Llame al método BeginTransaction del objeto SqlConnection para marcar el comienzo de la transacción. El método BeginTransaction devuelve una referencia a la transacción. Esta referencia se asigna a los objetos SqlCommand que están inscritos en la transacción.

  2. Asigne el objeto Transaction a la propiedad Transaction del objeto SqlCommand que se va a ejecutar. Si el comando se ejecuta en una conexión con una transacción activa y el objeto Transaction no se ha asignado a la propiedad Transaction del objeto Command, se inicia una excepción.

  3. Ejecute los comandos necesarios.

  4. Llame al método Commit del objeto SqlTransaction para completar la transacción, o al método Rollback para finalizarla. Si la conexión se cierra o elimina antes de que se hayan ejecutado los métodos Commit o Rollback, la transacción se revierte.

En el siguiente código de ejemplo se muestra la lógica transaccional utilizando ADO.NET con Microsoft SQL Server.

Using connection As New SqlConnection(connectionString)
    connection.Open()

    ' Start a local transaction.
    Dim sqlTran As SqlTransaction = connection.BeginTransaction()

    ' Enlist a command in the current transaction.
    Dim command As SqlCommand = connection.CreateCommand()
    command.Transaction = sqlTran

    Try
        ' Execute two separate commands.
        command.CommandText = _
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')"
        command.ExecuteNonQuery()
        command.CommandText = _
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')"
        command.ExecuteNonQuery()

        ' Commit the transaction
        sqlTran.Commit()
        Console.WriteLine("Both records were written to database.")

    Catch ex As Exception
        ' Handle the exception if the transaction fails to commit.
        Console.WriteLine(ex.Message)

        Try
            ' Attempt to roll back the transaction.
            sqlTran.Rollback()

        Catch exRollback As Exception
            ' Throws an InvalidOperationException if the connection 
            ' is closed or the transaction has already been rolled 
            ' back on the server.
            Console.WriteLine(exRollback.Message)
        End Try
    End Try
End Using
using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();

    // Start a local transaction.
    SqlTransaction sqlTran = connection.BeginTransaction();

    // Enlist a command in the current transaction.
    SqlCommand command = connection.CreateCommand();
    command.Transaction = sqlTran;

    try
    {
        // Execute two separate commands.
        command.CommandText =
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
        command.ExecuteNonQuery();
        command.CommandText =
          "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
        command.ExecuteNonQuery();

        // Commit the transaction.
        sqlTran.Commit();
        Console.WriteLine("Both records were written to database.");
    }
    catch (Exception ex)
    {
        // Handle the exception if the transaction fails to commit.
        Console.WriteLine(ex.Message);

        try
        {
            // Attempt to roll back the transaction.
            sqlTran.Rollback();
        }
        catch (Exception exRollback)
        {
            // Throws an InvalidOperationException if the connection 
            // is closed or the transaction has already been rolled 
            // back on the server.
            Console.WriteLine(exRollback.Message);
        }
    }
}

Vea también

Conceptos

Transacciones distribuidas (ADO.NET)

Integración de System.Transactions con SQL Server (ADO.NET)

Otros recursos

Transacciones y simultaneidad (ADO.NET)