Condividi tramite


Transazioni locali (ADO.NET)

Le transazioni in ADO.NET consentono di associare più attività in modo da poterle eseguire come un'unità di lavoro singola. Si supponga, ad esempio, 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 le due attività non vengono eseguite correttamente, verrà eseguito il rollback dei due aggiornamenti.

Determinazione del tipo di transazione

Una transazione è considerata locale quando è composta da una sola fase e viene gestita direttamente dal database. Le transazioni sono considerate distribuite, invece, quando vengono coordinate da un monitoraggio delle transazioni e sono completate con meccanismi fail-safe (quale il commit in due fasi).

Ogni provider di dati .NET Framework dispone di un oggetto Transaction per l'esecuzione delle transazioni locali. Per eseguire una transazione in un database di SQL Server, selezionare una transazione System.Data.SqlClient. Per una transazione Oracle utilizzare il provider System.Data.OracleClient. È inoltre disponibile una nuova classe DbTransaction che consente di scrivere codice indipendente dal provider che richiede transazioni.

NotaNota

Le transazioni più efficienti sono quelle eseguite sul server.Se si utilizza un database SQL Server in cui sono ampiamente utilizzate le transazioni esplicite, è consigliabile scrivere queste transazioni come stored procedure utilizzando l'istruzione BEGIN TRANSACTION Transact-SQL.Per ulteriori informazioni sull'esecuzione di transazioni sul lato server, vedere la documentazione online di SQL Server.

Esecuzione di una transazione con una singola connessione

In ADO.NET è possibile controllare le transazioni mediante 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 utilizzando 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.

NotaNota

Il metodo EnlistDistributedTransaction non deve essere utilizzato 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 2005 e, se non vengono generate eccezioni, viene eseguito il commit. Se, invece, viene generata un'eccezione, il codice del blocco catch esegue il rollback della transazione. 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, utilizzare 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 seguente viene illustrata la logica transazionale utilizzando 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);
        }
    }
}

Vedere anche

Concetti

Transazioni distribuite (ADO.NET)

Integrazione di System.Transactions con SQL Server (ADO.NET)

Altre risorse

Transazioni e concorrenza (ADO.NET)