Passaggio 2: Estensione di una transazione tra componenti
Obiettivi
In questo passaggio si apprenderà quanto segue:
- Flusso delle transazioni
- Modalità di voto di più oggetti in una transazione
Descrizione
Passaggio 1: Creazione di un componente transazionale illustra come scrivere un componente transazionale semplice che aggiorna le informazioni sull'autore nel database Pubs di Microsoft SQL Server. Il passaggio 2 mostra cosa accade quando una transazione viene estesa tra più componenti.
In linea con il modello di programmazione COM+, UpdateAuthorAddress
chiama un altro componente nel corso del completamento del suo lavoro. Il secondo componente, ValidateAuthorAddress
, convalida l'indirizzo dell'autore e restituisce i risultati al chiamante, UpdateAuthorAddress
.
A differenza del chiamante, ValidateAuthorAddress
non richiede una transazione, ma può comunque partecipare alla transazione del chiamante. In questo passaggio il valore dell'attributo della transazione è impostato su Supported, come illustrato nella figura seguente, che estende la transazione esistente al nuovo oggetto .
Il valore dell'attributo Supportato estende (o scorre) una transazione esistente solo quando il chiamante è transazionale. Quando UpdateAuthorAddress
chiama ValidateAuthorAddress
, COM+ esamina innanzitutto il contesto del chiamante per verificare se è transazionale. COM+ esamina quindi gli attributi del servizio impostati su ValidateAuthorAddress
e assegna al nuovo oggetto lo stesso identificatore di transazione assegnato all'oggetto chiamante. Per comprendere meglio questo processo, vedere Attivazione del contesto.
Poiché condividono lo stesso identificatore di transazione, entrambi gli oggetti devono completare correttamente il lavoro o COM+ interrompe la transazione (annullando eventuali modifiche apportate al database Pubs).
Tutti gli oggetti che partecipano a un voto di transazione per eseguire il commit o interrompere la transazione. Il voto si verifica in modo esplicito quando si includono le istruzioni di voto nel codice, come illustrato nell'estrazione seguente dal codice di esempio del passaggio 1, che crea il UpdateAuthorAddress
componente:
' Everything works.
contextstate.SetMyTransactionVote TxCommit
contextstate.SetDeactivateOnReturn True
Exit Sub
UnexpectedError:
' There's an error.
contextstate.SetMyTransactionVote TxAbort
contextstate.SetDeactivateOnReturn True
Il voto si verifica anche in modo implicito, come avviene nel ValidateAuthorAddress
componente. A meno che l'oggetto non dichiari diversamente, COM+ presuppone che il lavoro di un oggetto sia stato completato correttamente, ma che non sia pronto per essere disattivato. COM+ presuppone quanto segue:
contextstate.SetMyTransactionVote TxCommit
contextstate.SetDeactivateOnReturn False
Quando ValidateAuthorAddress
torna al chiamante, COM+ legge il suo voto come commit. COM+ non conta i voti fino a quando non disattiva l'oggetto radice, ovvero il primo oggetto nella transazione in questo caso, l'oggetto UpdateAuthorAddress
.
Codice di esempio
Il ValidateAuthorAddress
componente esegue un semplice controllo dell'indirizzo dell'autore. Poiché UpdateAuthorAddress
non vota in modo esplicito, COM+ usa le impostazioni di voto predefinite.
Option Explicit
'
' Purpose: This class is used for validating an author's address
' (presumably right before updating that address in the
' database).
'
' Notes: This component could be in a transaction or not; it doesn't
' matter because it doesn't touch any data in a database.
'
Public Function ValidateAuthorAddress( _
ByVal strAddress As String, _
ByVal strCity As String, _
ByVal strState As String, _
ByVal strZip As String) As Boolean
' Default is to validate unless something is found to be wrong.
ValidateAuthorAddress = True
' Invalidate authors who live in New York City
' and authors who live in Montana.
'
If strCity = "New York" And strState = "New York" Then
ValidateAuthorAddress = False
ElseIf strState = "Montana" Then
ValidateAuthorAddress = False
End If
' Done
End Function
Riepilogo
L'impostazione dell'attributo di transazione di un componente su Supported può comportare la creazione del nuovo oggetto nella transazione dell'oggetto chiamante. COM+ esamina il contesto del chiamante per determinare lo stato transazionale del nuovo oggetto. Se il chiamante è transazionale, COM+ passa la transazione al nuovo oggetto.
Tutti gli oggetti che partecipano alla stessa transazione condividono un identificatore di transazione comune, che COM+ legge dal contesto dell'oggetto.
Ogni oggetto in una transazione vota in modo indipendente da altri oggetti. COM+ conta i voti quando l'oggetto radice viene disattivato.
È possibile attivare o disattivare il voto di transazione di un oggetto tra commit e interruzione finché COM+ non disattiva l'oggetto o finché COM+ non disattiva l'oggetto radice e termina la transazione. Solo l'ultima impostazione di voto conta. Le interfacce IContextState e IObjectContext forniscono metodi e che producono risultati di voto simili, come illustrato nella tabella seguente. È possibile usare entrambe le interfacce per votare in modo esplicito in una transazione.
COM+ imposta il voto di un oggetto sull'equivalente di EnableCommit a meno che il componente non voti in modo esplicito.
Il voto in modo esplicito può ridurre la durata complessiva della transazione e rilasciare blocchi di risorse costosi.