Condividi tramite


Transazioni locali

Si applica a: .NET Framework .NET .NET Standard

Scarica ADO.NET

Le transazioni in ADO.NET vengono usate quando si vogliono associare più attività in modo che vengano eseguite come una singola unità di lavoro. Ad esempio, si supponga che un'applicazione esegua due attività. Ovvero che prima aggiorni una tabella con le informazioni sull'ordine e che, successivamente, aggiorni una tabella contenente le informazioni d'inventario addebitando gli articoli ordinati. Se una delle attività non viene eseguita correttamente, verrà eseguito il rollback di entrambi gli aggiornamenti.

Determinazione del tipo di transazione

Una transazione è considerata locale quando è composta da una sola fase e viene gestita direttamente dal database. Una transazione è considerata distribuita quando viene coordinata da un monitoraggio delle transazioni e usa meccanismi fail-safe (quale il commit in due fasi) per la risoluzione.

Il provider di dati Microsoft SqlClient per SQL Server include un proprio oggetto SqlTransaction per l'esecuzione di transazioni locali nei database di SQL Server. Anche altri provider di dati .NET forniscono oggetti Transaction specifici. È anche disponibile una classe DbTransaction che consente di scrivere codice indipendente dal provider che richiede transazioni.

Nota

Le transazioni sono più efficienti quando vengono eseguite nel server. Se si usa un database SQL Server in cui sono ampiamente usate le transazioni esplicite, è consigliabile scrivere queste transazioni come stored procedure usando l'istruzione BEGIN TRANSACTION Transact-SQL.

Esecuzione di una transazione usando una singola connessione

In ADO.NET è possibile controllare le transazioni con l'oggetto Connection. È possibile avviare una transazione locale con il metodo BeginTransaction. Una volta iniziata una transazione, è possibile inserire un comando nell'elenco della transazione usando la proprietà Transaction di un oggetto Command. In seguito è possibile eseguire il commit o il rollback delle modifiche apportate nell'origine dati in base all'esito corretto o errato dei componenti della transazione.

Nota

Il metodo EnlistDistributedTransaction non deve essere usato per una transazione locale.

L'ambito della transazione si limita alla connessione. Nell'esempio seguente viene eseguita una transazione esplicita composta da due comandi separati nel blocco try. I comandi eseguono le istruzioni INSERT sulla tabella Production.ScrapReason nel database di esempio AdventureWorks di SQL Server e, se non vengono generate eccezioni, viene eseguito il commit. Il codice nel blocco catch esegue il rollback della transazione se viene generata un'eccezione. Allo stesso modo, se la transazione viene interrotta oppure la connessione viene chiusa prima del completamento della transazione, viene eseguito automaticamente il rollback della transazione.

Esempio

Per eseguire una transazione, usare la procedura seguente:

  1. Chiamare il metodo BeginTransaction dell'oggetto SqlConnection per contrassegnare l'inizio della transazione. Il metodo BeginTransaction restituisce un riferimento alla transazione. Questo riferimento viene assegnato agli oggetti SqlCommand contenuti nell'elenco della transazione.

  2. Assegnare l'oggetto Transaction alla proprietà Transaction dell'oggetto SqlCommand da eseguire. Se un comando viene eseguito su una connessione con una transazione attiva e l'oggetto Transaction non è stato assegnato alla proprietà Transaction dell'oggetto Command, viene generata un'eccezione.

  3. Eseguire i comandi richiesti.

  4. Chiamare il metodo Commit dell'oggetto SqlTransaction per completare la transazione oppure il metodo Rollback per interrompere la transazione. Se la connessione viene chiusa o eliminata prima che venga eseguito il metodo Commit o Rollback, viene eseguito il rollback della transazione.

Nell'esempio di codice riportato di seguito viene illustrata la logica transazionale usando il provider di dati Microsoft SqlClient per 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);
                }
            }
        }
    }
}

Vedi anche