Condividi tramite


Passaggio 3: Riutilizzo dei componenti

Obiettivi

In questo passaggio si apprenderà quanto segue:

  • Componenti riutilizzabili.
  • Come pianificare la riutilizzabilità.

Descrizione

Due parti precedenti di questa introduzione ai servizi COM+, Passaggio 1: Creazione di un componente transazionale e Passaggio 2: Estensione di una transazione tra più componenti illustra come scrivere un componente che chiama un secondo componente per facilitare il completamento di alcune operazioni, l'aggiornamento delle informazioni sull'autore nel database Microsoft SQL Server Pubs; tutto il lavoro è protetto da una singola transazione. I componenti di esempio sono incentrati sul lavoro di aggiornamento dei dati di un autore e sulla verifica dell'indirizzo dell'autore e sull'elaborazione delle transazioni fornita da COM+, sull'attivazione JIT e sulla protezione della concorrenza.

Questo passaggio illustra come riutilizzare i componenti creati nei passaggi 1 e 2 e esamina ciò che significa per la progettazione di tali componenti. Come illustrato nella figura seguente, significa creare un nuovo componente, AddNewAuthor, che aggiunge nuovi autori al database chiamando UpdateAuthorAddress.

Diagram that shows the flow when reusing components.

Oltre a riutilizzare la funzionalità del componente esistente, AddNewAuthor chiama un altro nuovo componente denominato ValidateAuthorName. Come illustrato nella figura precedente, ValidateAuthorName non è transazionale. Il valore dell'attributo della transazione per questo componente viene lasciato all'impostazione predefinita (Non supportato) per escludere il lavoro dalla transazione. Come illustrato nel codice di esempio del passaggio 3, ValidateAuthorName esegue query di sola lettura nel database e l'errore di questa attività secondaria non deve avere la possibilità di interrompere la transazione. Tuttavia, il valore dell'attributo AddNewAuthor della transazione del componente è impostato su Obbligatorio.

I AddNewAuthorcomponenti , UpdateAuthorAddresse ValidateAuthorAddress votano tutti nella transazione. In questa transazione è AddNewAuthor l'oggetto radice. COM+ rende sempre il primo oggetto creato nella transazione l'oggetto radice.

In questo esempio, il riutilizzo del UpdateAuthorAddress componente è semplice: COM+ fornisce automaticamente i servizi previsti. Tuttavia, i risultati sarebbero diversi se il valore dell'attributo della transazione del UpdateAuthorAddress componente fosse inizialmente impostato su Richiede nuovo anziché Obbligatorio. Sulla superficie, entrambe le impostazioni appaiono simili; entrambe garantiscono una transazione. Richiede new, tuttavia, avvia sempre una nuova transazione, mentre Required avvia una nuova transazione solo quando il chiamante dell'oggetto non è transazionale. Da questo aspetto è importante configurare UpdateAuthorAddress attentamente e attentamente. In caso contrario, COM+ potrebbe aver interpretato la richiesta del servizio in modo diverso, generando due transazioni non correlate, come illustrato nella figura seguente, anziché una.

Diagram that shows the flow when reusing components with

Nota

Quando si riutilizzano i componenti, assicurarsi che i servizi siano configurati per supportare il risultato desiderato.

 

Codice di esempio

Il componente AddNewAuthor esegue aggiunte batch di nuovi autori consentendo all'oggetto di rimanere attivo fino a quando il client non rilascia il riferimento all'oggetto.

Option Explicit
'
'   Purpose:   This class is used for adding a new author.
'
'   Notes:    IMPT:  This component implicitly assumes that it will
'             always run in a transaction. Undefined results may 
'             otherwise occur.
'
'  AddNewAuthor
'
Public Sub AddNewAuthor( _
                        ByVal strAuthorFirstName As String, _
                        ByVal strAuthorLastName As String, _
                        ByVal strPhone As String, _
                        ByVal strAddress As String, _
                        ByVal strCity As String, _
                        ByVal strState As String, _
                        ByVal strZip As String, _
                        ByVal boolContracted As Boolean)
  ' Handle any errors.
  On Error GoTo UnexpectedError

  ' Verify component is in a transaction.
  ' The VerifyInTxn subroutine is described in Step 1.
  VerifyInTxn

  ' Get our object context.
  Dim objcontext As COMSVCSLib.ObjectContext
  Set objcontext = GetObjectContext

  ' Get the IContextState object.
  Dim contextstate As COMSVCSLib.IContextState
  Set contextstate = objcontext

  ' Validate that the author is OK.
  ' The ValidateAuthorName function is described after this function.
  Dim oValidateAuthName As Object
  Dim bValidAuthor As Boolean
  Set oValidateAuthName = CreateObject("ComplusPrimer.ValidateAuthorName")
  bValidAuthor = oValidateAuthName.ValidateAuthorName( _
    strAuthorFirstName, strAuthorLastName)
  If Not bValidAuthor Then
    Err.Raise 999999, "The AddNewAuthor component", _
      "You tried to add an author on the banned list!"
  End If
  
  ' Open the connection to the database.
  Dim conn As ADODB.Connection
  Set conn = CreateObject("ADODB.Connection")

  ' Specify the OLE DB provider.
  conn.Provider = "SQLOLEDB"

  ' Connect using Windows Authentication.
  Dim strProv As String
  strProv = "Server=MyDBServer;Database=pubs;Trusted_Connection=yes"

  ' Open the database.
  conn.Open strProv

  ' Tell the database to actually add the author; use empty strings 
  ' for this part and rely on the UpdateAuthorAddress 
  ' component to validate the address/phone/etc data.
  ' Default Contract flag is off.
  Dim strUpdateString As String
  strUpdateString = "insert into authors values(_
                     '789-65-1234'," & _
                     strAuthorLastName & ", " & _
                     strAuthorFirstName & ", " & _
                     "'(555) 555-5555', ', ', ', '98765', "

  If boolContracted Then
    strUpdateString = strUpdateString + "1)"
  Else
    strUpdateString = strUpdateString + "0)"
  End If

  conn.Execute strUpdateString
  
  ' Close the connection; this potentially allows 
  ' another component in the same transaction to
  ' reuse the connection from the connection pool.
  conn.Close
  Set conn = Nothing
  
  ' Create the UpdateAuthorAddress component.
  Dim oUpdateAuthAddr As Object
  Set oUpdateAuthAddr = CreateObject("ComplusPrimer.UpdateAuthorAddress")
  
  ' The component throws an error if anything goes wrong.
  oUpdateAuthAddr.UpdateAuthorAddress "", strPhone, _
    strAddress, strCity, strState, strZip
    
  Set oUpdateAuthAddr = Nothing
  
  ' Everything works--commit the transaction.
  contextstate.SetMyTransactionVote TxCommit
  
  '  Design issue:  Allow batch additions of new
  '  authors in one transaction, or should each new author be added
  '  in a single new transaction?
  contextstate.SetDeactivateOnReturn False
  Exit Sub
  
UnexpectedError:
  ' There's an error.
  contextstate.SetMyTransactionVote TxAbort
  contextstate.SetDeactivateOnReturn True
  
End Sub

Il ValidateAuthorName componente convalida i nomi degli autori prima AddNewAuthor di aggiungere il nome al database. Questo componente genera un errore al chiamante se si verifica un evento imprevisto.

Option Explicit
'
'   Purpose:   This class is used for validating authors before
'              adding them to the database.
'
'   Notes:   This component doesn't need to be in a transaction because
'            it is performing read-only queries on the database,
'            especially since these queries are not overlapping with
'            any updates of end-user data. If an unexpected error
'            happens, let the error go back to the caller who
'            needs to handle it.
'

Public Function ValidateAuthorName( _
                        ByVal strAuthorFirstName As String, _
                        ByVal strAuthorLastName As String _
                        ) As Boolean
  ValidateAuthorName = False

  ' Open the connection to the database.
  Dim conn As ADODB.Connection
  Set conn = CreateObject("ADODB.Connection")

  ' Specify the OLE DB provider.
  conn.Provider = "SQLOLEDB"

  ' Connect using Windows Authentication.
  Dim strProv As String
  strProv = "Server=MyDBServer;Database=pubs;Trusted_Connection=yes"

  ' Open the database.
  conn.Open strProv

  ' Suppose another hypothetical table has been added to the Pubs 
  ' database, one that contains a list of banned authors.
  Dim rs As ADODB.Recordset
  Set rs = conn.Execute("select * from banned_authors")
  
  ' Loop through the banned-author list looking for the specified
  ' author.
  While Not rs.EOF
    If rs.Fields("FirstName") = strAuthorFirstName And _
      rs.Fields("LastName") = strAuthorLastName Then
        ' This is a banned author.
        conn.Close
        Set conn = Nothing
        Set rs = Nothing
        Exit Function
    End If
    rs.MoveNext
  Wend
  
  ' None of the added authors found in the banned list.
  ValidateAuthorName = True
  conn.Close
  Set conn = Nothing
  Set rs = Nothing
End Function

Riepilogo

  • In alcuni casi non si vuole che un componente voti nella transazione.
  • COM+ non applica l'attivazione JIT o la protezione della concorrenza su componenti non transazionali. È possibile configurare questi servizi separatamente.
  • La configurazione di un componente chiamante influisce sul modo in cui COM+ interpreta le richieste di servizio del componente chiamato.

Passaggio 1: Creazione di un componente transazionale

Passaggio 2: Estensione di una transazione tra più componenti

Configurazione delle transazioni

Progettazione per la scalabilità