Inserimento in una transazione distribuita

L'oggetto Connection, in presenza di una transazione attiva, prevede l'inserimento automatico nella transazione distribuita. L'inserimento automatico in una transazione avviene anche quando la connessione viene aperta o recuperata dal pool di connessioni. È possibile disattivare l'inserimento automatico nelle transazioni esistenti specificando Enlist=false come parametro della stringa di connessione per una SqlConnection oppure OLE DB Services=-7 come parametro della stringa di connessione per una OleDbConnection.

Se l'inserimento automatico è disattivato, sarà possibile inserirsi in una transazione distribuita esistente utilizzando il metodo EnlistDistributedTransaction dell'oggetto Connection. L'inserimento in un transazione distribuita esistente assicura che se l'intera transazione viene confermata o annullata, le modifiche apportate dal codice all'origine dati saranno anch'esse confermate o annullate.

EnlistDistributedTransaction è particolarmente indicato quando si effettua il pool di oggetti business. Se si effettua il pool di un oggetto business con una connessione aperta, l'inserimento automatico nella transazione avverrà solo quando la connessione viene aperta o estratta dal pool di connessioni. Se vengono condotte più transazioni utilizzando l'oggetto business di cui si effettua il pool, la connessione aperta per tale oggetto non verrà automaticamente inserita nelle nuove transazioni. In questo caso, è possibile disattivare l'inserimento automatico della Connection nelle transazioni e inserire la Connection nelle transazioni utilizzando EnlistDistributedTransaction.

EnlistDistributedTransaction accetta un solo argomento di tipo ITransaction, ovvero un riferimento alla transazione esistente. Dopo la chiamata di Connection.EnlistDistributedTransaction, tutte le modifiche apportate all'origine dati utilizzando la Connection verranno incluse nella transazione.

Nota   Prima di chiamare EnlistDistributedTransaction, è necessario aprire la Connection.

Attenzione   Se la Connection ha già iniziato una transazione utilizzando BeginTransaction, EnlistDistributedTransaction restituirà una Exception. Nel caso però di una transazione locale avviata sull'origine dati (ad esempio, eseguendo in modo esplicito l'istruzione BEGIN TRANSACTION tramite un SqlCommand), la chiamata di EnlistDistributedTransaction comporterà l'annullamento della transazione locale e l'inserimento nella transazione distribuita esistente, come richiesto. Non verrà fornita alcuna notifica dell'annullamento della transazione locale e occorrerà gestire tutte le transazioni locali non avviate tramite BeginTransaction.

Nell'esempio che segue viene mostrata una richiesta di transazione avanzata da una pagina ASP.NET. L'inserimento nella transazione è assolto dal codice ADO.NET contenuto nella pagina.

<%@Page Transaction="Required" %> 
<%@Import Namespace="System.Data"%>
<%@Import Namespace="System.Data.SqlClient"%>
<%@Import Namespace="System.EnterpriseServices"%>

<html>
<Script Runat="SERVER" Language="VB">

Sub Page_Load()
  Dim ns As NorthwindSample = New NorthwindSample()

  Dim customerId As String = "CUST1"
  Dim companyName As String = "New Company Name"

  Try
    ns.AddCustomer(customerId, companyName, CType(ContextUtil.Transaction, ITransaction))
    ContextUtil.SetComplete()
    Response.Write("Customer " & customerId & " added.")
  Catch e As Exception
    ContextUtil.SetAbort()
    Response.Write("Customer " & customerId & " not added. An exception of type " & _
                   e.GetType().ToString() & " was encountered.")
  End Try
End Sub


Public Class NorthwindSample

  Public Sub AddCustomer(customerId As String, companyName As String, trans As ITransaction)
  
    Dim nwindConn As SqlConnection = New SqlConnection("Data Source=localhost;Integrated Security=SSPI;" & _
                                                      "Initial Catalog=Northwind;Enlist=false;")

    Dim cmd As SqlCommand = New SqlCommand("INSERT INTO Customers (CustomerID, CompanyName) " & _
                                           "Values(@CustomerId, @CompanyName)", nwindConn)
    cmd.Parameters.Add("@CustomerId", SqlDbType.VarChar, 5).Value = customerId
    cmd.Parameters.Add("@CompanyName", SqlDbType.VarChar, 40).Value = companyName

    nwindConn.Open()

    If Not trans Is Nothing Then
      nwindConn.EnlistDistributedTransaction(trans)
    End If

    Try
      cmd.ExecuteNonQuery()
    Catch e As SqlException
      Throw e
    finally
      nwindConn.Close()
    End Try
  End Sub

End Class
</Script>
</html>
[C#]
<%@Page Transaction="Required" %> 
<%@Import Namespace="System.Data"%>
<%@Import Namespace="System.Data.SqlClient"%>
<%@Import Namespace="System.EnterpriseServices"%>

<html>
<Script Runat="SERVER" Language="C#">

void Page_Load()
{
  NorthwindSample ns = new NorthwindSample();

  string customerId = "CUST1";
  string companyName = "New Company Name";

  try
  {
    ns.AddCustomer(customerId, companyName, (ITransaction)ContextUtil.Transaction);
    ContextUtil.SetComplete();
    Response.Write("Customer " + customerId + " added.");
  }
  catch (Exception e)
  {
    ContextUtil.SetAbort();
    Response.Write("Customer " + customerId + " not added. An exception of type " + e.GetType() + " was encountered.");
  }
}


public class NorthwindSample
{
  public void AddCustomer(string customerId, string companyName, ITransaction trans)
  {
    SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;" +
                                                "Initial Catalog=Northwind;Enlist=false;");

    SqlCommand cmd = new SqlCommand("INSERT INTO Customers (CustomerID, CompanyName) " +
                                    "Values(@CustomerId, @CompanyName)", nwindConn);
    cmd.Parameters.Add("@CustomerId", SqlDbType.VarChar, 5).Value = customerId;
    cmd.Parameters.Add("@CompanyName", SqlDbType.VarChar, 40).Value = companyName;

    nwindConn.Open();

    if (trans != null)
      nwindConn.EnlistDistributedTransaction(trans);

    try
    {
      cmd.ExecuteNonQuery();
    }
    catch (SqlException e)
    {
      throw(e);
    }
    finally
    {
      nwindConn.Close();
    }
  }
}
</Script>
</html>

Vedere anche

Utilizzo di provider di dati .NET Framework per accedere ai dati | Classe OleDbConnection | Classe OleDbTransaction | Classe SqlConnection | Classe SqlTransaction | Classe OdbcConnection | Classe OdbcTransaction