Compartir a través de


Transacciones locales

Se aplica a: .NET Framework .NET .NET Standard

Descargar ADO.NET

Las transacciones de ADO.NET se usan cuando se quiere 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 no se puede realizar alguna de las tareas, las dos actualizaciones se revierten.

Determinación del tipo de transacción

Una transacción se considera local cuando consta de una única fase y la base de datos la controla directamente. Una transacción se considera distribuida cuando se coordina mediante un monitor de transacciones y usa mecanismos a prueba de errores (como la confirmación en dos fases) para su resolución.

El proveedor de datos SqlClient de Microsoft para SQL Server tiene un objeto SqlTransaction propio para realizar transacciones locales en bases de datos de SQL Server. Otros proveedores de datos de .NET también proporcionan objetos Transaction propios. Además, existe una clase DbTransaction disponible para escribir código independiente del proveedor que requiere transacciones.

Nota

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.

Realización de una transacción con una sola 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.

Nota

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 sobre la tabla Production.ScrapReason de la base de datos de ejemplo AdventureWorks de SQL Server, que se confirman si no se inicia ninguna excepción. El código del bloque catch revierte la transacción si se lanza 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 ejemplo de código siguiente se muestra la lógica transaccional al usar el proveedor de datos SqlClient de Microsoft para SQL Server.

using System;
using Microsoft.Data.SqlClient;

class Program
{
    static void Main(string[] args)
    {
        string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog = AdventureWorks";

        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);
                }
            }
        }
    }
}

Consulte también