Transazioni automatiche e classi .NET Framework
Le istanze di una classe .NET Framework possono prendere parte a una transazione automatica, sempre che la classe venga appositamente preparata. Ciascuna risorsa cui accede un oggetto o un'istanza di una classe viene inserita nella transazione. Se ad esempio un oggetto utilizza ADO.NET per accreditare denaro su un conto in un database, il gestore delle risorse del database determinerà se tale oggetto può essere eseguito in una transazione. In caso positivo l'impiego del database nella transazione avverrà automaticamente.
Per preparare una classe a partecipare a una transazione automatica, attenersi alla seguente procedura:
Applicare TransactionAttribute alla classe.
Derivare la classe dalla classe ServicedComponent.
Firmare l'assembly con un nome sicuro.
Per firmare l'assembly utilizzando gli attributi, creare una coppia di chiavi mediante Sn.exe:
sn -k TestApp.snk
Per firmare l'assembly con un nome sicuro, aggiungere l'attributo di assembly AssemblyKeyFileAttribute o AssemblyKeyNameAttribute, specificando il nome del file contenente la coppia di chiavi.
<assembly: AssemblyKeyFileAttribute("TestApp.snk")> [C#] [assembly: AssemblyKeyFileAttribute("TestApp.snk")]
Per informazioni dettagliate, vedere Firma di un assembly con un nome sicuro.
Registrare l'assembly che contiene la classe nel catalogo COM+.
Se il client che chiama le istanze della classe è gestito da Common Language Runtime, la registrazione verrà effettuata automaticamente. Se tuttavia si prevede che possano essere create e chiamate istanze della classe da un client non gestito, utilizzare .NET Services Installation Tool (Regsvcs.exe) per eseguire la registrazione manualmente.
L'esempio che segue mostra come applicare TransactionAttribute a una classe derivata dalla classe ServicedComponent.
<Transaction(TransactionOption.Required)> Public Class SampleClass
Inherits ServicedComponent
'. . .
End Class
[C#]
[Transaction(TransactionOption.Required)]
public class SampleClass(): ServicedComponent
{
//. . .
}
Quando si applica l'attributo di transazione è possibile utilizzare indifferentemente Transaction, transaction, TransactionAttribute e transactionattribute. Utilizzando ad esempio Transaction o transactionattribute, si otterranno risultati identici.
Nella tabella che segue sono elencate e descritte tutte le variazioni dei costruttori.
Valore dell'attributo | Descrizione |
---|---|
Disabled | Elimina il controllo delle transazioni automatiche sull'oggetto. Un oggetto cui è applicato questo valore di attributo può avvalersi direttamente del Distributed Transaction Coordinator (DTC) per un supporto transazionale.
|
NotSupported | Indica che l'oggetto non viene eseguito nell'ambito di una transazione. Quando una richiesta viene elaborata, il corrispondente contesto dell'oggetto viene creato senza transazione, indipendentemente dal fatto che esista una transazione attiva.
|
Supported | Indica che l'oggetto viene eseguito nel contesto di una transazione esistente. Se non è in corso alcuna transazione, l'oggetto verrà eseguito senza transazioni.
|
Required
(valore predefinito) |
Indica che l'oggetto richiede una transazione. Viene eseguito nell'ambito di una transazione esistente. Se non è in corso alcuna transazione, l'oggetto ne inizierà una.
|
RequiresNew | Indica che l'oggetto richiede una transazione e che viene iniziata una nuova transazione per ciascuna richiesta.
|
Esempio di classe
L'esempio di codice che segue illustra vari elementi di una transazione automatica. In questo esempio sia la classe transazionale che il client che chiama la classe sono gestiti dal runtime.
' -----------------------------------------------------------------
' 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;
}
}
Vedere anche
Transazioni automatiche | Opzioni di voto nelle transazioni automatiche | Scrittura dei componenti serviti