Compartir a través de


Transacciones automáticas y clases de .NET Framework

Las instancias de una clase de .NET Framework pueden participar en una transacción automática mientras se prepara la clase para ello. Cada recurso al que ha obtenido acceso una instancia de clase, o un objeto, se inscribe en la transacción. Por ejemplo, si un objeto utiliza ADO.NET para enviar dinero a una cuenta de una base de datos, el administrador de recursos para la base de datos determina si el objeto se debe ejecutar en una transacción. En caso afirmativo, inscribe automáticamente la base de datos en la transacción.

Utilice el proceso siguiente para preparar una clase con el fin de que participe en una transacción automática:

  1. Aplique TransactionAttribute a la clase.

  2. Derive la clase de la clase ServicedComponent.

  3. Firmar un ensamblado con un nombre seguro

    Para firmar un ensamblado utilizando atributos, cree un par de claves mediante Sn.exe:

    sn -k TestApp.snk
    

    Agregue el atributo de ensamblado AssemblyKeyFileAttribute o AssemblyKeyNameAttribute, especificando el nombre del archivo que contiene el par de claves para firmar el ensamblado con un nombre seguro.

    <assembly: AssemblyKeyFileAttribute("TestApp.snk")>
    [C#]
    [assembly: AssemblyKeyFileAttribute("TestApp.snk")]
    

    Para obtener más detalles, vea Firmar un ensamblado con un nombre seguro.

  4. Registre el ensamblado que contiene la clase con el catálogo de COM+.

    Si Common Language Runtime administra el cliente que llama a instancias de la clase, el registro se realiza automáticamente. Sin embargo, si se prevé que un código no administrado pudiera utilizar y crear instancias de la clase, se ha de utilizar la herramienta Instalación de servicios de .NET (Regsvcs.exe) para realizar el registro manualmente.

El ejemplo siguiente muestra cómo se aplica el atributo TransactionAttribute a una clase derivada de la clase ServicedComponent.

<Transaction(TransactionOption.Required)> Public Class SampleClass
   Inherits ServicedComponent
   '. . .
End Class
[C#]
[Transaction(TransactionOption.Required)]
public class SampleClass(): ServicedComponent
{
  //. . .
}

Cuando se aplica el atributo de transacción, se puede utilizar Transaction, transaction, TransactionAttribute y transactionattribute indistintamente. Por ejemplo, se puede utilizar Transaction o transactionattribute obteniéndose los mismos resultados.

La tabla siguiente enumera y describe cada variación de constructor.

Valor de atributo Descripción
Disabled Elimina el control de transacciones automáticas en el objeto. Un objeto que tenga aplicado este valor de atributo delega en DTC (Coordinador de transacciones distribuidas de Microsoft) que será quien administre directamente la realización de la transacción.
[Transaction(TransactionOption.Disabled)]
NotSupported Indica que el objeto no se ejecute dentro del ámbito de una transacción. Cuando se procesa una solicitud, se crea su contexto de objeto sin una transacción, independientemente de que haya una transacción activa.
[Transaction(TransactionOption.NotSupported)]
Supported Indica que el objeto se ejecute en el contexto de una transacción existente, si existe alguna. Si no existen transacciones, el objeto se ejecuta sin una transacción.
[Transaction(TransactionOption.Supported)]
Required

(predeterminado)

Indica que el objeto requiere una transacción. Se ejecuta en el ámbito de una transacción existente, si existe alguna. Si no existen transacciones, el objeto inicia una transacción.
[Transaction(TransactionOption.Required)]
RequiresNew Indica que el objeto requiere una transacción y se inicia una transacción nueva para cada solicitud.
[Transaction(TransactionOption.RequiresNew)]

Clase de ejemplo

El ejemplo de código siguiente muestra varios elementos de una transacción automática. En este ejemplo, el motor de tiempo de ejecución administra tanto la clase transaccional como el cliente que llama a la clase.

' -----------------------------------------------------------------
' TestApp.vb
' Generate a Strong name: 
'    sn -k TestApp.snk
' Compile the code:
'    vbc /target:exe /r:System.EnterpriseServices.dll TestApp.vb
' Run TestApp:
'    start TestApp.exe
' -----------------------------------------------------------------
Option Explicit
Option Strict

Imports System
Imports System.Runtime.CompilerServices
Imports System.EnterpriseServices
Imports System.Reflection

'Registration details.
'COM+ application name as it appears in the COM+ catalog.
<assembly: ApplicationName("TestApp")>
'Strong name for assembly.
<assembly: AssemblyKeyFileAttribute("TestApp.snk")>

<Transaction(TransactionOption.Required)> Public Class Account
   Inherits ServicedComponent
   
   'Provides SetComplete behavior in the absence of exceptions.
   <AutoComplete()> Public Sub Debit(amount As Integer)
      ' Do some database work. Any exception thrown here aborts the 
      ' transaction; otherwise, transaction commits.
   End Sub
End Class

Public Class client
   Public Shared Sub Main()
      Dim accountX As New Account()
      accountX.Debit(100)
      Environment.Exit(0)
   End Sub
End Class
[C#]
// -----------------------------------------------------------------
// TestApp.cs
// Generate a Strong name: 
//    sn -k TestApp.snk
// Compile the code:
//    csc /target:exe /r:System.EnterpriseServices.dll TestApp.cs
// Run TestApp:
//    start TestApp.exe
// -----------------------------------------------------------------
using System;
using System.Runtime.CompilerServices;
using System.EnterpriseServices;
using System.Reflection;

//Registration details.
//COM+ application name as it appears in the COM+ catalog.
[assembly: ApplicationName("TestApp")]
//Strong name for assembly.
[assembly: AssemblyKeyFileAttribute("TestApp.snk")]

[Transaction(TransactionOption.Required)]
public class Account : ServicedComponent
{
  //Provides SetComplete behavior in the absence of exceptions.
  [AutoComplete]
  public void Debit(int amount)
  {
     // Do some database work. Any exception thrown here aborts the 
     // transaction; otherwise, transaction commits.
  }
}

public class client
{
  public static int Main() 
  {
    Account accountX = new Account();
    accountX.Debit(100);
    return 0;
  }
}

Vea también

Transacciones automáticas | Votación en una transacción automática | Escribir componentes con servicio