Partager via


Étape 3 : Réutilisation des composants

Objectifs

Dans cette étape, vous allez découvrir les éléments suivants :

  • Composants réutilisables.
  • Comment planifier la réutilisation.

Description

Deux parties précédentes de cette introduction des services COM+, Étape 1 : Création d’un composant transactionnel et Étape 2 : Extension d’une transaction sur plusieurs composants montrent comment écrire un composant qui appelle un deuxième composant pour faciliter l’exécution d’un travail, la mise à jour des informations de l’auteur dans la base de données Microsoft SQL Server Pubs; tout le travail est protégé par une seule transaction. Les exemples de composants se sont concentrés sur le travail de mise à jour des données d’un auteur et de vérification de l’adresse de l’auteur, et com+ a fourni le traitement des transactions, l’activation JIT et la protection de la concurrence.

Cette étape montre comment réutiliser les composants créés aux étapes 1 et 2 et examine ce que cela signifie pour la conception de ces composants. Comme le montre l’illustration suivante, cela signifie la création d’un nouveau composant, AddNewAuthor, qui ajoute de nouveaux auteurs à la base de données en appelant UpdateAuthorAddress.

Diagramme montrant le flux lors de la réutilisation des composants.

En plus de réutiliser les fonctionnalités de composant existantes, AddNewAuthor appelle un autre nouveau composant appelé ValidateAuthorName. Comme le montre l’illustration précédente, ValidateAuthorName est non transactionnel. La valeur de l’attribut de transaction pour ce composant est laissée à son paramètre par défaut (Non pris en charge) pour exclure son travail de la transaction. Comme indiqué dans l’exemple de code de l’étape 3, ValidateAuthorName exécute des requêtes en lecture seule sur la base de données, et l’échec de cette tâche mineure ne doit pas avoir le potentiel d’abandonner la transaction. Toutefois, la valeur de l’attribut de transaction du AddNewAuthor composant est définie sur Obligatoire.

Les AddNewAuthorcomposants , UpdateAuthorAddresset ValidateAuthorAddress votent tous dans la transaction. Dans cette transaction, AddNewAuthor est l’objet racine. COM+ fait toujours du premier objet créé dans la transaction l’objet racine.

Dans cet exemple, la réutilisation du UpdateAuthorAddress composant est facile : COM+ fournit automatiquement les services attendus. Toutefois, les résultats seraient différents si la valeur de l’attribut de transaction du UpdateAuthorAddress composant était initialement définie sur Nécessite nouveau au lieu de Obligatoire. Sur la surface, les deux paramètres semblent similaires ; les deux garantissent une transaction. Nécessite New, toutefois, démarre toujours une nouvelle transaction, tandis que Obligatoire démarre une nouvelle transaction uniquement lorsque l’appelant de l’objet n’est pas transactionnel. Vous pouvez voir à partir de cela combien il était important de configurer UpdateAuthorAddress soigneusement et soigneusement. Sinon, COM+ peut avoir interprété la demande de service différemment, générant deux transactions non liées, comme illustré dans l’illustration suivante, au lieu d’une seule.

Diagramme montrant le flux lors de la réutilisation des composants avec « Nécessite de nouveaux ».

Notes

Lorsque vous réutilisez des composants, assurez-vous que les services sont configurés pour prendre en charge le résultat souhaité.

 

Exemple de code

Le composant AddNewAuthor effectue des ajouts par lots de nouveaux auteurs en permettant à l’objet de rester actif jusqu’à ce que le client libère sa référence à l’objet.

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

Le ValidateAuthorName composant valide les noms d’auteur avant d’ajouter AddNewAuthor le nom à la base de données. Ce composant renvoie une erreur à son appelant si quelque chose d’inattendu se produit.

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

Récapitulatif

  • Il arrive que vous ne souhaitiez pas qu’un composant vote dans la transaction.
  • COM+ n’applique pas l’activation JIT ou la protection de la concurrence sur les composants non transactionnels. Vous pouvez configurer ces services séparément.
  • La configuration d’un composant appelant affecte la façon dont COM+ interprète les demandes de service du composant appelé.

Étape 1 : Création d’un composant transactionnel

Étape 2 : Extension d’une transaction sur plusieurs composants

Configuration des transactions

Conception pour la scalabilité