Compartilhar via


Etapa 3: Reutilizar componentes

Objetivos

Nesta etapa, você aprenderá sobre o seguinte:

  • Componentes reutilizáveis.
  • Como planejar a reutilização.

Descrição

Duas partes anteriores desta cartilha de serviços COM+, Etapa 1: Criando um componente transacional e Etapa 2: Estendendo uma transação entre vários componentes, mostram como escrever um componente que chama um segundo componente para ajudar na conclusão de algum trabalho, atualizando as informações do autor no banco de dados Microsoft SQL Server Pubs, todo o trabalho é protegido por uma única transação. Os componentes de exemplo se concentraram no trabalho de atualizar os dados de um autor e verificar o endereço do autor, e o COM+ forneceu processamento de transações, ativação JIT e proteção de simultaneidade.

Esta etapa demonstra como reutilizar os componentes criados nas etapas 1 e 2 e examina o que isso significa para o design desses componentes. Como mostrado na ilustração a seguir, isso significa criar um novo componente, , AddNewAuthorque adiciona novos autores ao banco de dados chamando UpdateAuthorAddress.

Diagram that shows the flow when reusing components.

Além de reutilizar a funcionalidade do componente existente, AddNewAuthor chama outro novo componente chamado ValidateAuthorName. Como mostra a ilustração anterior, ValidateAuthorName não é transacional. O valor do atributo de transação para esse componente é deixado em sua configuração padrão (Não suportado) para excluir seu trabalho da transação. Conforme mostrado no código de exemplo da etapa 3, ValidateAuthorName executa consultas somente leitura no banco de dados e a falha dessa tarefa secundária não deve ter o potencial de anular a transação. No entanto, o valor do atributo de transação do AddNewAuthor componente é definido como Obrigatório.

O AddNewAuthor, UpdateAuthorAddresse ValidateAuthorAddress todos os componentes votam na transação. Nesta transação, AddNewAuthor é o objeto raiz. COM+ sempre torna o primeiro objeto criado na transação o objeto raiz.

Neste exemplo, a reutilização do componente é fácil — o UpdateAuthorAddress COM+ fornece automaticamente os serviços esperados. No entanto, os resultados seriam diferentes se o valor do atributo de transação do UpdateAuthorAddress componente fosse inicialmente definido como Requer Novo em vez de Obrigatório. Na superfície, ambas as configurações parecem semelhantes; ambos garantem uma transação. Requer Novo, no entanto, sempre inicia uma nova transação, enquanto Necessário inicia uma nova transação somente quando o chamador do objeto não é transacional. Você pode ver a partir disso como era importante configurar UpdateAuthorAddress com cuidado e atenção. Caso contrário, o COM+ poderia ter interpretado a solicitação de serviço de forma diferente, gerando duas transações não relacionadas, conforme mostrado na ilustração a seguir, em vez de uma.

Diagram that shows the flow when reusing components with

Observação

Ao reutilizar componentes, verifique se os serviços estão configurados para oferecer suporte ao resultado desejado.

 

Código de exemplo

O componente AddNewAuthor executa adições em lote de novos autores, permitindo que o objeto permaneça ativo até que o cliente libere sua referência ao objeto.

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

O ValidateAuthorName componente valida os nomes dos autores antes AddNewAuthor de adicionar o nome ao banco de dados. Esse componente lança um erro de volta para seu chamador se algo inesperado acontecer.

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

Resumo

  • Há momentos em que você não quer que um componente vote na transação.
  • O COM+ não impõe a ativação JIT ou a proteção de simultaneidade em componentes não transacionais. Você pode configurar esses serviços separadamente.
  • A configuração de um componente de chamada afeta como COM+ interpreta as solicitações de serviço do componente chamado.

Etapa 1: Criando um componente transacional

Etapa 2: Estendendo uma transação entre vários componentes

Configurando transações

Projetando para escalabilidade