Compartilhar via


Manipulando erros em componentes enfileirados

Ocasionalmente, ocorre uma situação em que uma mensagem não pode ser entregue com êxito ao seu destino pretendido, geralmente devido a um problema com o sistema ou configuração. Por exemplo, a mensagem pode ser direcionada para uma fila que não existe ou a fila de destino pode não estar em um estado para receber. O movimentador de mensagens é uma ferramenta que move todas as mensagens do serviço de enfileiramento de mensagens com falha de uma fila para outra para que possam ser repetidas. O utilitário de movimentação de mensagens é um objeto Automation que pode ser invocado com um VBScript.

Ferramenta administrativa de serviços de componentes

Não se aplica.

Visual Basic

O código de exemplo a seguir mostra como criar um objeto MessageMover, definir as propriedades necessárias e iniciar a transferência. Para usá-lo do Visual Basic, adicione uma referência à biblioteca de tipos de serviços COM+.

Observação

Para usar o objeto MessageMover, você deve ter o serviço de enfileiramento de mensagens instalado no computador e o aplicativo especificado por AppName deve ter o enfileiramento habilitado. Para obter informações sobre como instalar o serviço de enfileiramento de mensagens, consulte Ajuda e suporte no menu Iniciar .

 

Function MyMessageMover( _
  strSource As String, _
  strDest As String _
) As Boolean  ' Return False if any errors occur.

    MyMessageMover = False  ' Initialize the function.
    On Error GoTo My_Error_Handler  ' Initialize error handling.

    Dim lngMovedMessages As Long
    Dim objMessageMover As COMSVCSLib.MessageMover
    Set objMessageMover = CreateObject("QC.MessageMover")
    objMessageMover.SourcePath = strSource
    objMessageMover.DestPath = strDest
    lngMovedMessages = objMessageMover.MoveMessages

    MsgBox lngMovedMessages & " messages moved from " & _
      strSource & " to " & strDest

    MyMessageMover = True  ' Successful end to procedure
    Set objMessageMover = Nothing
    Exit Function

My_Error_Handler:  ' Replace with specific error handling.
    MsgBox "Error # " & Err.Number & " (Hex: " & Hex(Err.Number) _
      & ")" & vbNewLine & Err.Description
    Set objMessageMover = Nothing
    lngMovedMessages = -1
End Function

O código do Visual Basic a seguir mostra como chamar a função MyMessageMover.

Sub Main()
  ' Replace AppName with the name of a COM+ application.
  If Not MyMessageMover(".\private$\AppName_deadqueue", ".\AppName") Then
      MsgBox "MyMessageMover failed."
  End If
End Sub

O caminho de origem da mensagem é a fila de repouso final. É a fila morta, que é uma fila privada do serviço de enfileiramento de mensagens e é chamada de AppName_deadqueue. As mensagens serão movidas para cá se a transação for abortada repetidamente quando tentada na quinta fila de repetição. Com a ferramenta de movimentação de mensagens, você pode mover a mensagem de volta para a primeira fila, que é chamada AppName. Para obter mais informações sobre filas de repetição, consulte Erros do lado do servidor.

Se os atributos da fila permitirem, o movimentador de mensagens moverá as mensagens de forma transitória para que as mensagens não sejam perdidas ou duplicadas em caso de falha durante a movimentação. A ferramenta preserva todas as propriedades de mensagem que podem ser preservadas ao mover mensagens de uma fila para outra.

Se as mensagens forem geradas por chamadas de componentes em fila COM+, o utilitário de movimentação de mensagens preservará o identificador de segurança do chamador original à medida que move mensagens entre filas. Se as filas de destino e origem forem transacionais, toda a operação será feita de forma transitória. Se as filas de origem ou de destino não forem transacionais, a operação não será executada em uma transação. Uma falha inesperada (como uma falha) e a reinicialização de uma movimentação não transacional podem duplicar a mensagem que está sendo movida no momento da falha.

C/C++

O código de exemplo a seguir mostra como criar um objeto MessageMover, definir as propriedades necessárias e iniciar a transferência. O método ErrorDescription é descrito em Interpretando códigos de erro.

Observação

Para usar o objeto MessageMover, você deve ter o serviço de enfileiramento de mensagens instalado no computador e o aplicativo especificado por AppName deve ter o enfileiramento habilitado. Para obter informações sobre como instalar o serviço de enfileiramento de mensagens, consulte Ajuda e suporte no menu Iniciar .

 

#include <windows.h>
#include <stdio.h>
#import "C:\WINDOWS\system32\ComSvcs.dll"
#include "ComSvcs.h"
#include "StrSafe.h"  

BOOL MyMessageMover (OLECHAR* szSource, OLECHAR* szDest) {
    IUnknown * pUnknown = NULL;
    IMessageMover * pMover = NULL;
    HRESULT hr = S_OK;
    BSTR bstrSource = NULL;
    BSTR bstrDest = NULL;
    unsigned int uMaxLen = 255;  // Maximum length of szMyApp

try {
    // Test the input strings to make sure they're OK to use.
    hr = StringCchLengthW(szSource, uMaxLen, NULL);
    if (FAILED (hr)) throw(hr);
    hr = StringCchLengthW(szDest, uMaxLen, NULL);
    if (FAILED (hr)) throw(hr);
    
    // Convert the input strings to BSTRs.
    bstrSource = SysAllocString(szSource);
    bstrDest = SysAllocString(szDest);

    // Create a MessageMover object and get its IUnknown.
    hr = CoCreateInstance(CLSID_MessageMover, NULL, 
      CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnknown);
    if (FAILED (hr)) throw(hr);    

    // Get the IMessageMover interface.
    hr = pUnknown->QueryInterface(IID_IMessageMover, (void**)&pMover); 
    if (FAILED (hr)) throw(hr);

    // Put the source and destination files.
    hr = pMover->put_SourcePath(bstrSource);
    if (FAILED (hr)) throw(hr);
    hr = pMover->put_DestPath(bstrDest);
    if (FAILED (hr)) throw(hr);

    // Move the messages.
    LONG lCount = -1;
    hr = pMover->MoveMessages(&lCount);
    if (FAILED (hr)) throw(hr);
    printf("%ld messages moved from %S to %S.\n", 
      lCount, bstrSource, bstrDest);

    // Clean up.
    SysFreeString(bstrDest);
    SysFreeString(bstrSource);
    pUnknown->Release();
    pUnknown = NULL;
    pMover->Release();
    pMover = NULL;
    return (TRUE);
}  // try

catch(HRESULT hr) {  // Replace with specific error handling.
    printf("Error # %#x: ", hr);
    ErrorDescription(hr);
    SysFreeString(bstrDest);
    SysFreeString(bstrSource);
    if (NULL != pUnknown) pUnknown->Release();
    pUnknown = NULL;
    if (NULL != pMover) pMover->Release();
    pMover = NULL;
    return (FALSE);
}catch(...) {
    printf("An unexpected exception occurred.\n");
    throw;
}        
}  // MyMessageMover

O código C++ a seguir mostra como chamar a função MyMessageMover.

#include <windows.h>
#include <stdio.h>

#define _WIN32_DCOM  // To use CoInitializeEx()

void main() 
{
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (FAILED (hr)) {
        printf("CoInitializeEx failed: Error # %#x\n", hr);
        exit(0);  // Replace with specific error handling.
    }
    if (! MyMessageMover(L".\\private$\\AppName_deadqueue", 
      L".\\AppName"))
        printf("MyMessageMover failed.\n");
    CoUninitialize();
}

O caminho de origem da mensagem é a fila de repouso final. É a fila morta, que é uma fila privada do serviço de enfileiramento de mensagens e é chamada de AppName_deadqueue. As mensagens serão movidas para cá se a transação for abortada repetidamente quando tentada na quinta fila de repetição. Com a ferramenta de movimentação de mensagens, você pode mover a mensagem de volta para a primeira fila, que é chamada AppName. Para obter mais informações sobre filas de repetição, consulte Erros do lado do servidor.

Se os atributos da fila permitirem, o movimentador de mensagens moverá as mensagens de forma transitória para que as mensagens não sejam perdidas ou duplicadas em caso de falha durante a movimentação. A ferramenta preserva todas as propriedades de mensagem que podem ser preservadas ao mover mensagens de uma fila para outra.

Se as mensagens forem geradas por chamadas de componentes em fila COM+, o utilitário de movimentação de mensagens preservará o identificador de segurança do chamador original à medida que move mensagens entre filas. Se as filas de destino e origem forem transacionais, toda a operação será feita de forma transitória. Se as filas de origem ou de destino não forem transacionais, a operação não será executada em uma transação. Uma falha inesperada (como uma falha) e a reinicialização de uma movimentação não transacional podem duplicar a mensagem que está sendo movida no momento da falha.

Comentários

COM+ lida com abortamentos do lado do servidor (player) movendo a mensagem que está falhando para uma fila de "descanso final" diferente, para tirá-la do caminho. O ouvinte e o player não podem repetir continuamente uma mensagem que aborta. Em muitos casos, a transação anulada pode ser corrigida executando uma ação no servidor.

Erros de componentes em fila