Notas sobre o Release


20.5 Cenários de Utilização

As Funções do MQSeries podem ser utilizadas em uma grande variedade de cenários. Essa seção reexibirá alguns dos cenários mais comuns, incluindo as Mensagens Básicas, a Conectividade do Aplicativo e a Publicação de Dados.

20.5.1 Mensagens Básicas

A forma mais básica de mensagens com as Funções do MQSeries DB2 ocorre quando todos os aplicativos do banco de dados conectam-se ao mesmo servidor do DB2. Os cientes podem ser locais para o servidor do banco de dados ou distribuídos em um ambiente de rede.

Em um cenário simples, o Cliente A invoca a função MQSEND para enviar uma cadeia definida pelo usuário para a localização de serviço padrão. As funções do MQSeries são executadas dentro do DB2 no servidor do banco de dados. Em algum momento posterior, o Cliente B invoca a função MQRECEIVE para remover a mensagem na cabeça da fila definida pelo serviço padrão e retorna-a para o cliente. Novamente, as funções do MQSeries para executar esse trabalho são executadas pelo DB2.

Os clientes do banco de dados podem utilizar mensagens simples de várias maneiras. Alguns usos comuns para as mensagens são:

O cenário a seguir estende o cenário simples descrito acima, para incorporar mensagens remotas. Isto é, uma mensagem é enviada entre a Máquina A e a Máquina B. A seqüência de etapas é a seguinte:

  1. O Cliente do DB2 executa uma chamada MQSEND, especificando um serviço de destino que foi definido para representar uma fila remota na Máquina B.
  2. As funções do MQSeries DB2 executam o trabalho atual do MQSeries de enviar a mensagem. O servidor do MQSeries em uma Máquina A aceita a mensagem e garante que ela a entregará para o destino definido pela definição de ponto de serviço e pela configuração atual do MQSeries da Máquina A. O servidor determina que esta é uma fila na Máquina B. Ele tenta entregar a mensagem para o servidor do MQSeries na Máquina B, transparentemente, repetindo conforme necessário.
  3. O servidor do MQSeries na Máquina B aceita a mensagem do servidor na Máquina A e a coloca na fila de destino da Máquina B.
  4. Um cliente do MQSeries na Máquina B solicita a mensagem na cabeça da fila.

20.5.2 Enviando Mensagens

Utilizando MQSEND, um usuário ou um desenvolvedor do DB2 escolhe quais dados enviar, para onde enviá-los e quando ele será enviado. Na indústria, este é comumentemente chamado "Enviar e Esquecer," significando que o emissor apenas envia uma mensagem, confiando nos protocolos de entrega garantidos do MQSeries para assegurar-se de que a mensagem atinge seu destino. Os exemplos a seguir ilustram isso.

Exemplo 4: Para enviar uma cadeia definida pelo usuário para o ponto de serviço myPlace com a política highPriority:

VALUES DB2MQ.MQSEND('myplace','highPriority','test')

Aqui, a política highPriority refere-se a uma política definida no Repositório da AMI que define a prioridade do MQSeries para o nível mais alto e talvez ajusta melhor outras qualidades de serviço, tal como persistência.

O conteúdo da mensagem pode ser composto de qualquer combinação legal de dados do SQL e especificados pelo usuário. Isso inclui funções aninhadas, operadores e coletas. Por exemplo, determinado uma tabela EMPLOYEE, com VARCHAR colunas LASTNAME, FIRSTNAME e DEPARTMENT, para enviar uma mensagem que contém essas informações para cada empregado no DEPARTMENT 5LGA você fará o seguinte:

Exemplo 5:

SELECT DB2MQ.MQSEND(LASTNAME || ' ' || FIRSTNAME || ' ' || DEPARTMENT)
   FROM EMPLOYEE
      WHERE DEPARTMENT = '5LGA'

Se esta tabela também tiver uma coluna AGE inteira, ela poderá ser incluída como segue:

Exemplo 6:

SELECT DB2MQ.MQSEND
      (LASTNAME || ' ' || FIRSTNAME || ' ' || DEPARTMENT|| ' ' || char(AGE))
   FROM EMPLOYEE
      WHERE DEPARTMENT = '5LGA'

Se a tabela EMPLOYEE tivesse uma coluna RESUME do tipo CLOB em vez de uma coluna AGE, uma mensagem contendo as informações de cada funcionário no DEPARTMENT 5LGA poderia ser emitida com o seguinte:

Exemplo 7:

SELECT DB2MQ.MQSEND
      (clob(LASTNAME) || ' ' || clob(FIRSTNAME) || ' ' || clob(DEPARTMENT) || ' ' ||
 RESUME))
   FROM EMPLOYEE
      WHERE DEPARTMENT = '5LGA'

Exemplo 8:

Finalmente, o exemplo a seguir mostra como o conteúdo da mensagem pode ser derivado utilizando qualquer expressão de SQL válida. Dada uma segunda tabela DEPT com as colunas VARCHAR DEPT_NO e DEPT_NAME, é possível enviar mensagens contendo o LASTNAME e o DEPT_NAME do funcionário:

Exemplo 8:

SELECT DB2MQ.MQSEND(e.LASTNAME || ' ' || d.DEPTNAME) FROM EMPLOYEE e, DEPT d
   WHERE e.DEPARTMENT = d.DEPTNAME

20.5.3 Recuperando Mensagens

As Funções do MQSeries DB2 permitem que as mensagens sejam recebidas ou lidas. A diferença entre a leitura e o recebimento é que a leitura retorna a mensagem na cabeça de uma fila sem removê-la da fila, enquanto que as operações de recebimento fazem com que a mensagem seja removida da fila. Uma mensagem recuperada utilizando uma operação de recebimento pode apenas ser recuperada uma vez, enquanto que uma mensagem recuperada utilizando a operação de leitura permite que a mesma mensagem seja recuperada muitas vezes. Os exemplos a seguir demonstram isto:

Exemplo 8:

VALUES DB2MQ.MQREAD()

Esse exemplo retorna uma cadeia VARCHAR contendo a mensagem na cabeça da fila definida pelo serviço padrão que utiliza a qualidade de política de serviço padrão. É importante observar que se nenhuma mensagem estiver disponível para ser lida, um valor nulo será retornado. A fila não é alterada por esta operação.

Exemplo 9:

VALUES DB2MQ.MQRECEIVE('Employee_Changes')

O exemplo acima mostra como uma mensagem pode ser removida da cabeça da fila definida pelo serviço Employee_Changes que utiliza a política padrão.

Um recurso muito poderoso do DB2 é a capacidade de gerar uma tabela de uma função definida pelo usuário (ou fornecida pelo DB2-). Você pode explorar esse recurso de função da tabela para permitir que o conteúdo de uma fila seja materializado como uma tabela do DB2. O exemplo a seguir demonstra a forma mais simples disso:

Exemplo 10:

SELECT t.* FROM tabela ( DB2MQ.MQREADALL()) t 

Essa consulta retorna uma tabela que consiste em todas as mensagens na fila definidas pelo serviço padrão e os metadados sobre estas mensagens. Enquanto o destino completo da estrutura da tabela retornada é definido no Apêndice, a primeira coluna reflete o conteúdo da mensagem e as colunas restantes contêm os metadados. Para retornar apenas as mensagens, o exemplo pode ser regravado:

Exemplo 11:

SELECT t.MSG FROM tabela (DB2MQ.MQREADALL()) t

A tabela retornada por uma função da tabela não é diferente de uma tabela recuperada diretamente do banco de dados. Isso significa que você pode utilizar essa tabela em uma grande variedade de maneiras. Por exemplo, você pode unir o conteúdo da tabela com outra tabela ou contar o número de mensagens em uma fila:

Exemplo 12:

SELECT t.MSG, e.LASTNAME
   FROM tabela (DB2MQ.MQREADALL() ) t, EMPLOYEE e
      WHERE t.MSG = e.LASTNAME

Exemplo 13:

SELECT COUNT(*) FROM tabela (DB2MQ.MQREADALL()) t

Você também pode ocultar o fato de que a origem da tabela é uma fila, através da criação de uma exibição em uma função da tabela. Por exemplo, o exemplo a seguir cria uma exibição chamada NEW_EMP na fila referida pelo serviço nomeado NEW_EMPLOYEES:

Exemplo 14:

CREATE VIEW NEW_EMP (msg) AS
   SELECT t.msg FROM tabela (DB2MQ.MQREADALL()) t

Nesse caso, a exibição é definida apenas com uma única coluna que contém uma mensagem inteira. Se as mensagens são apenas estruturadas, para a instância que contém dois campos de comprimento fixo, é correto utilizar as funções incorporadas do DB2 para analisar a mensagem nas duas colunas. Por exemplo, se você souber que as mensagens enviadas para uma fila específica sempre contêm um sobrenome de 18 caracteres seguido de um primeiro nome de 18 caracteres, você poderá definir uma exibição que contém cada campo como uma coluna separada como segue:

Exemplo 15:

CREATE VIEW NEW_EMP2 AS
   SELECT left(t.msg,18) AS LNAME, right(t.msg,18) AS FNAME
   FROM tabela(DB2MQ.MQREADALL()) t

Um novo recurso do DB2 Stored Procedure Builder, o Assistente Assist do MQSeries, pode ser utilizado para criar novas funções e exibições da tabela do DB2 que irão mapear estruturas de mensagens delimitadas para as colunas.

Finalmente é desejável armazenar o conteúdo de uma ou mais mensagens no banco de dados. Isso pode ser feito utilizando a energia completa do SQL para manipular e armazenar o conteúdo da mensagem. Talvez o exemplo mais simples disso é:

Exemplo 16:

INSERT INTO MESSAGES
   SELECT t.msg FROM tabela (DB2MQ.MQRECEIVEALL()) t

Determinado uma tabela MESSAGES, com uma única coluna VARCHAR(2000), a instrução acima irá inserir as mensagens da fila de serviços padrão na tabela. Essa técnica pode ser aprimorada para abranger uma grande variedade de circunstâncias.

20.5.4 Conectividade de Aplicativo a Aplicativo

A integração de aplicativos é um elemento comum em muitas soluções. Se integrar um aplicativo comprado em uma infra-estrutura existente ou apenas integrar um aplicativo recentemente desenvolvido em um ambiente existente, muitas vezes, estaremos voltados com a tarefa de unir uma coleta heterogênea de subsistemas juntos para formar todo um trabalho. O MQSeries é comumentemente exibido como uma ferramenta essencial de integrar aplicativos. Acessível na maioria dos ambientes de hardware, software e de linguagem, o MQSeries fornece o meio de interconectar uma coleção muito heterogênea de aplicativos.

Essa seção discutirá alguns cenários de integração do aplicativo e como eles podem ser utilizados com o DB2. Como o tópico é muito abrangente, um tratamento compreensivo de Integração do Aplicativo vai além do escopo desse trabalho. Entretanto, o foco está exatamente em dois tópicos simples: comunicação de Pedido/Resposta e MQSeries Integrator e Publish/Subscribe.

20.5.4.1 Comunicações de Pedido/Resposta

O método de comunicações de Pedido/Resposta (R/R) é uma técnica muito comum para um ID de aplicativo solicitar os serviços de outro. Uma maneira de fazer isso é para o solicitador enviar uma mensagem para o provedor de serviço solicitando o mesmo trabalho a ser executado. Quando o trabalho foi concluído, o provedor pode decidir enviar os resultados (ou apenas uma confirmação de conclusão) de volta para o solicitador. Mas utilizar as técnicas de mensagens básicas descritas acima, não há nada que conecta o pedido do emissor à resposta do provedor de serviço. A menos que o solicitador aguarde uma resposta antes de continuar, algum mecanismo deve ser utilizado para associar cada resposta a seu pedido. Em vez de forçar o desenvolvedor a criar esse mecanismo, o MQSeries fornece um identificador de correlação que permite a correlação de mensagens em uma troca.

Enquanto existe um número de maneiras no qual esse mecanismo pode ser utilizado, o mais simples é para o solicitador marcar uma mensagem com um identificador de correlação conhecido utilizando, por exemplo, o seguinte:

Exemplo 17:

DB2MQ.MQSEND ('myRequester','myPolicy','SendStatus:cust1','Req1')

Essa instrução inclui um parâmetro final Req1 na instrução MQSEND acima, para indicar o identificador de correlação do pedido.

Para receber uma resposta a esse pedido específico, utilize a instrução MQRECEIVE correspondente para recuperar seletivamente a primeira mensagem definida pelo serviço indicado que corresponda a esse identificador de correlação, como a seguir:

Exemplo 18:

DB2MQ.MQRECEIVE('myReceiver','myPolicy','Req1')

Se o aplicativo que atende o pedido estiver ocupado e o solicitador emitir o MQRECEIVE acima antes da resposta ser enviada, nenhuma mensagem que corresponda a esse identificador de correlação será encontrada.

Para receber o pedido de serviço e o identificador de correlação, uma instrução como a seguinte é utilizada:

Exemplo 19:

SELECT msg, correlid FROM tabela (DB2MQ.MQRECEIVEALL
('aServiceProvider','myPolicy',1)) t

Isso retorna a mensagem e o identificador de correlação do primeiro pedido do aServiceProvider de serviço.

Quando o serviço foi executado, ele envia a mensagem de resposta para a fila descrita pelo aRequester. Entretanto, o solicitador de serviço pode ter realizado outro trabalho. De fato, não existe nenhuma garantia que o pedido de serviço inicial será respondido dentro do tempo definido. Os tempos limites do nível de aplicativo tais como este, devem ser gerenciado pelo desenvolvedor; o solicitador deve ser controlado para detectar a presença da resposta.

A vantagem de tal processamento assíncrono independente de tempo é que o solicitador e o provedor de serviço são executados completamente independentes um do outro. Estes podem ser utilizados para acomodar os ambientes nos quais os aplicativos são conectados apenas intermitentemente e mais ambientes orientados em batch nos quais vários pedidos ou respostas são agregados antes do processamento. Esse tipo de agregação é freqüentemente utilizado em ambientes de warehouse de dados, para atualizar periodicamente um warehouse de dados ou armazenamento de dados operacional.

20.5.4.2 Publicar/Associar

Publicação de Dados Simples

Outro cenário comum na integração de aplicativos é para um aplicativo notificar outros aplicativos sobre os eventos de interesse. Isso é facilmente feito enviando uma mensagem para uma fila monitorada por outro aplicativo. O conteúdo da mensagem pode ser uma cadeia definida pelo usuário ou pode ser composto de colunas do banco de dados. Muitas vezes, uma mensagem simples é tudo o que precisa para ser enviada utilizando a função MQSEND. Quando tais mensagens precisam ser enviadas concorrentemente para vários destinatários, o recurso da Lista de Distribuição da MQSeries AMI pode ser utilizado.

Uma lista de distribuição é definida utilizando a ferramenta AMI Administration. Uma lista de distribuição abrange uma lista de serviços individuais. Uma mensagem enviada para uma lista de distribuição é encaminhada para cada serviço definido dentro da lista. Isso é, especialmente, útil quando sabe-se que poucos serviços sempre estarão interessados em toda mensagem. O exemplo a seguir mostra o envio de uma mensagem para a lista de distribuição interestedParties:

Exemplo 20:

DB2MQ.MQSEND('interestedParties','informações de interesse geral');

Quando é requerido mais controle sobre as mensagens que os serviços específicos devem receber, uma capacidade de Publicar/Associar é necessária. Os sistemas de publicação/associação fornecem, tipicamente, um ambiente escalável e seguro no qual muitos assinantes podem ser registrados para receberem mensagens de vários publicadores. Para suportar essa capacidade da interface MQPublish poder ser utilizada, em conjunto com o recurso MQSeries Integrator ou MQSeries Publish/Subscribe.

O MQPublish permite que os usuários especifiquem, opcionalmente, um tópico a ser associado a uma mensagem. Os tópicos permitem um assinante para especificar mais claramente as mensagens a serem aceitas. A seqüência de etapas é a seguinte:

  1. Um administrador do MQSeries configura as capacidades do MQSeries Integrator publish/subscribe.
  2. Os aplicativos interessados associam os pontos de assinatura definidos pela configuração do MQSI, especificando, opcionalmente, os tópicos de interesse deles. Cada assinante seleciona os tópicos relevantes e também pode utilizar as técnicas de assinatura baseadas no conteúdo do MQSeries Integrator V2. É importante observar que as filas, conforme representadas por nomes de serviços, definem o assinante.
  3. Um aplicativo do DB2 publica uma mensagem para o ponto de serviço Tempo. As mensagens indicam se o tempo está Nevando com um tópico de Austin, notificando, assim, os assinantes interessados que o tempo em Austin está Nevando.
  4. Os mecanismos de publicação da mensagem atual são manipulados pelas funções do MQSeries fornecidas pelo DB2. A mensagem é enviada para o MQSeries Integrator utilizando o serviço nomeado Tempo.
  5. O MQSI aceita a mensagem do serviço de Tempo, executa qualquer processamento definido pela configuração do MQSI e determina quais assinaturas ele satisfaz. Em seguida, ele envia a mensagem para as filas do assinante cujos critérios atende.
  6. Os aplicativos que são associados ao serviço e Tempo e que registraram um interesse em Austin, receberão a mensagem Nevando em seu serviço de recebimento.

Para publicar esses dados utilizando todos os padrões e um tópico nulo, você utilizará a seguinte instrução:

Exemplo 21:

SELECT DB2MQ.MQPUBLISH(LASTNAME || ' ' || FIRSTNAME || '
                 ' || DEPARTMENT|| ' ' ||char(AGE))
   FROM EMPLOYEE
      WHERE DEPARTMENT = '5LGA'

Especificar completamente todos os parâmetros e simplificar a mensagem para conter apenas o LASTNAME, a instrução se parecerá:

Exemplo 22:

SELECT DB2MQ.MQPUBLISH('HR_INFO_PUB', 'SPECIAL_POLICY', LASTNAME,
   'ALL_EMP:5LGA', 'MANAGER')
   FROM EMPLOYEE
      WHERE DEPARTMENT = '5LGA'

Essa instrução publica mensagens para o serviço de publicação HR_INFO_PUB, utilizando o serviço SPECIAL_POLICY. As mensagens indicam que o emissor é o tópico MANAGER. A cadeia de tópicos demonstra que vários tópicos, concatenados utilizando um ':' podem ser especificados. Nesse exemplo, o uso de dois tópicos permite que os assinantes sejam registrados para ALL_EMP ou apenas 5LGA para receber essas mensagens.

Para receber mensagens publicadas, primeiro você deve registrar seu interesse em mensagens que contêm um determinado tópico e indicar o nome do serviço do assinante para o qual as mensagens devem ser enviadas. É importante observar que um serviço do assinantes da AMI define um serviço intermediário e um serviço do receptor. O serviço intermediário é como o assinante que se comunica com o intermediário de publicar/associar e o serviço do receptor está onde as mensagens que correspondem ao pedido de assinatura serão enviadas. A instrução a seguir registra um interesse no tópico ALL_EMP.

Exemplo 23:

DB2MQ.MQSUBSCRIBE('aSubscriber', 'ALL_EMP')

Quando um aplicativo é associado, as mensagens publicadas com o tópico ALL_EMP serão enviadas para o serviço do receptor definido pelo serviço do assinante. Um aplicativo pode ter várias assinaturas concorrentes. Para obter as mensagens que atendem sua assinatura, qualquer uma das funções de recuperação de mensagem padrão podem ser utilizadas. Por exemplo, se o aSubscriber de serviço do assinante definir o serviço do receptor para ser aSubscriberReceiver, a instrução a seguir lerá não-destrutivamente a primeira mensagem:

Exemplo 24:

DB2MQ.MQREAD('aSubscriberReceiver')

Para determinar as mensagens e os tópicos em que eles foram publicados, você utilizará uma das funções da tabela. A instrução a seguir receberá as cinco primeiras mensagens do aSubscriberReceiver e exibirá a mensagem e o tópico:

Exemplo 25:

SELECT t.msg, t.topic FROM tabela (DB2MQ.MQRECEIVEALL('aSubscriberReceiver',
5)) t

Para ler todas as mensagens com o tópico ALL_EMP, você pode atuar sobre a energia do SQL para emitir:

Exemplo 26:

SELECT t.msg FROM tabela (DB2MQ.MQREADALL('aSubscriberReceiver')) t
   WHERE t.topic = 'ALL_EMP'
Nota:
É importante perceber que se o MQRECEIVEALL é utilizado com uma limitação, em seguida toda a fila será consumida, não apenas essas mensagens publicadas com o tópico ALL_EMP. Isso acontece porque a função da tabela é executada antes da limitação ser aplicada.

Quando você não estiver mais interessado em associar um tópico específico, é necessário desassociar explicitamente utilizando uma instrução tal como:

Exemplo 27:

DB2MQ.MQUNSUBSCRIBE('aSubscriber', 'ALL_EMP')

Quando essa instrução é emitida o intermediário de publicação/associação não entregará mais as mensagens correspondentes a essa assinatura.

Publicação Automática

Outra técnica importante no sistema de mensagens do banco de dados é a publicação automatizada. Utilizando o recurso de disparo dentro do DB2, você pode, opcionalmente, publicar mensagens como parte de uma invocação de disparo. Enquanto existem outras técnicas para publicação de dados automatizada, a abordagem baseada em disparo permite aos administradores ou aos desenvolvedores grande liberdade na construção do conteúdo e da flexibilidade da mensagem na definição das ações de disparo. Como com qualquer uso de disparos, deve ser prestar atenção na freqüência e no custo da execução. Os exemplos a seguir demonstram como os disparos podem ser utilizados com as Funções do MQSeries DB2.

O exemplo abaixo mostra como é fácil publicar uma mensagem todas vez que um novo empregado é contratado. Todos os usuários e aplicativos associados ao serviço HR_INFO_PUB comum interesse registrado em NEW_EMP, receberão uma mensagem contendo a data, o nome e o departamento de cada novo empregado.

Exemplo 28:

CREATE TRIGGER new_employee AFTER INSERT ON employee REFERENCING NEW AS n
      FOR EACH ROW MODE DB2SQL
      VALUES DB2MQ.MQPUBLISH('HR_INFO_PUB&',  'NEW_EMP',
      current date || ' ' || LASTNAME || ' ' || DEPARTMENT)


[ Início da Página | Página Anterior | Próxima Página | Índice | Índice Remissivo ]