Condividi tramite


Transazioni locali

Le transazioni in ADO.NET vengono usate quando si desidera associare più attività in modo che vengano eseguite come una singola unità di lavoro. Si supponga, ad esempio, che un'applicazione esegua due attività. Prima di tutto, aggiorna una tabella con le informazioni sull'ordine. In secondo luogo, aggiorna una tabella che contiene informazioni di inventario, a cui vengono addebitati gli articoli ordinati. Se una delle due attività ha esito negativo, viene eseguito il rollback di entrambi gli aggiornamenti.

Determinazione del tipo di transazione

Una transazione viene considerata una transazione locale quando si tratta di una transazione a singola fase e viene gestita direttamente dal database. Una transazione viene considerata come una transazione distribuita quando è coordinata da un monitoraggio delle transazioni e usa meccanismi non sicuri (ad esempio commit a due fasi) per la risoluzione delle transazioni.

Ogni provider di dati .NET Framework ha un proprio Transaction oggetto per l'esecuzione di transazioni locali. Se è necessario eseguire una transazione in un database di SQL Server, selezionare una System.Data.SqlClient transazione. Per una transazione Oracle, usare il System.Data.OracleClient provider. Inoltre, è disponibile una DbTransaction classe per la scrittura di codice indipendente dal provider che richiede transazioni.

Annotazioni

Le transazioni sono più efficienti quando vengono eseguite nel server. Se si usa un database di SQL Server che usa in modo completo le transazioni esplicite, è consigliabile scriverle come stored procedure usando l'istruzione BEGIN TRANSACTION Transact-SQL.

Esecuzione di una transazione tramite una singola connessione

In ADO.NET si controllano le transazioni con l'oggetto Connection . È possibile avviare una transazione locale con il BeginTransaction metodo . Dopo aver avviato una transazione, è possibile associare un comando a tale transazione utilizzando la proprietà Transaction di un oggetto Command. È quindi possibile eseguire il commit o il rollback delle modifiche apportate all'origine dati in base all'esito positivo o negativo dei componenti della transazione.

Annotazioni

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

L'ambito della transazione è limitato alla connessione. Nell'esempio seguente viene eseguita una transazione esplicita costituita da due comandi separati nel try blocco . I comandi eseguono istruzioni INSERT sulla tabella Production.ScrapReason nel database di esempio AdventureWorks SQL Server, di cui viene eseguito il commit se non vengono generate eccezioni. Il codice nel catch blocco esegue il rollback della transazione se viene generata un'eccezione. Se la transazione viene interrotta o la connessione viene chiusa prima del completamento della transazione, viene eseguito automaticamente il rollback.

Esempio

Seguire questa procedura per eseguire una transazione.

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

  2. Assegnare l'oggetto Transaction alla Transaction proprietà 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 necessari.

  4. Chiamare il Commit metodo dell'oggetto SqlTransaction per completare la transazione oppure chiamare il Rollback metodo per terminare la transazione. Se la connessione viene chiusa o eliminata prima dell'esecuzione di qualsiasi dei metodi Commit o Rollback, viene eseguito il rollback della transazione.

L'esempio di codice seguente illustra la logica transazionale usando ADO.NET con Microsoft SQL Server.

using (SqlConnection connection = new(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);
        }
    }
}
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

Vedere anche