Partilhar via


Gestão de Transações (Intercâmbio de Dados)

Depois de estabelecer uma conversa com um servidor, um cliente pode enviar transações para obter dados e serviços do servidor.

Os tópicos a seguir descrevem os tipos de transações que os clientes podem usar para interagir com um servidor.

Solicitar transação

Um aplicativo cliente pode usar a transação XTYP_REQUEST para solicitar um item de dados de um aplicativo de servidor. O cliente chama a funçãoDdeClientTransaction, especificando XTYP_REQUEST como o tipo de transação e especificando o item de dados que o aplicativo precisa.

A Biblioteca de Gerenciamento do Intercâmbio de Dados Dinâmicos (DDEML) passa a transação XTYP_REQUEST para o servidor, especificando o nome do tópico, o nome do item e o formato de dados solicitado pelo cliente. Se o servidor oferecer suporte ao tópico, item e formato solicitados, o servidor deverá retornar um identificador de dados que identifique o valor atual do item. O DDEML passa esse identificador para o cliente como o valor de retorno de DdeClientTransaction. O servidor deve retornar NULL se ele não suportar o tópico, item ou formato solicitado.

DdeClientTransaction usa o parâmetro lpdwResult para retornar um sinalizador de status de transação para o cliente. Se o servidor não processar a transação XTYP_REQUEST, DdeClientTransaction retornará NULL e lpdwResult apontará para o sinalizador DDE_FNOTPROCESSED ou DDE_FBUSY. Se o sinalizador DDE_FNOTPROCESSED for retornado, o cliente não poderá determinar por que o servidor não processou a transação.

Se um servidor não suportar a transação XTYP_REQUEST, ele deve especificar o sinalizador de filtro CBF_FAIL_REQUESTS na funçãoDdeInitialize. Esse sinalizador impede que o DDEML envie a transação para o servidor.

Transação Poke

Um cliente pode enviar dados não solicitados para um servidor usando DdeClientTransaction para enviar uma transação XTYP_POKE para a função de retorno de chamada de um servidor.

O aplicativo cliente primeiro cria um buffer que contém os dados a serem enviados para o servidor e, em seguida, passa um ponteiro para o buffer como parâmetro para DdeClientTransaction. Como alternativa, o cliente pode usar a funçãoDdeCreateDataHandle para obter um identificador de dados que identifica os dados e, em seguida, passar o identificador para DdeClientTransaction. Em ambos os casos, o cliente também especifica o nome do tópico, o nome do item e o formato de dados quando chama DdeClientTransaction.

O DDEML passa a transação XTYP_POKE para o servidor, especificando o nome do tópico, o nome do item e o formato de dados que o cliente solicitou. Para aceitar o item de dados e o formato, o servidor deve retornar DDE_FACK. Para rejeitar os dados, o servidor deve retornar DDE_FNOTPROCESSED. Se o servidor estiver muito ocupado para aceitar os dados, o servidor deverá retornar DDE_FBUSY.

Quando DdeClientTransaction retorna, o cliente pode usar o parâmetro lpdwResult para acessar o sinalizador de status da transação. Se o sinalizador estiver DDE_FBUSY, o cliente deve enviar a transação novamente mais tarde.

Se um servidor não suportar a transação XTYP_POKE, ele deverá especificar o sinalizador de filtro CBF_FAIL_POKES em DdeInitialize. Esse sinalizador impede que o DDEML envie essa transação para o servidor.

Aconselhar Transação

Um aplicativo cliente pode usar o DDEML para estabelecer um ou mais links para itens em um aplicativo de servidor. Quando esse link é estabelecido, o servidor envia atualizações periódicas sobre o item vinculado para o cliente (normalmente, sempre que o valor do item associado ao aplicativo de servidor muda). A vinculação estabelece um loop de aviso entre os dois aplicativos que permanece no lugar até que o cliente o termine.

Existem dois tipos de loops de aconselhamento: "quente" e "quente". Em um hot advise loop, o servidor envia imediatamente um identificador de dados que identifica o valor alterado. Em um loop de aviso quente, o servidor notifica o cliente de que o valor do item foi alterado, mas não envia o identificador de dados até que o cliente o solicite.

Um cliente pode solicitar um hot advise loop com um servidor especificando o tipo de transação XTYP_ADVSTART em uma chamada para DdeClientTransaction. Para solicitar um ciclo de aconselhamento quente, o cliente deve combinar a bandeira XTYPF_NODATA com o tipo de transação XTYP_ADVSTART. Em ambos os casos, o DDEML passa a transação XTYP_ADVSTART para a função de retorno de chamada DDE (Dynamic Data Exchange) do servidor. A função de retorno de chamada DDE do servidor deve examinar os parâmetros que acompanham a transação XTYP_ADVSTART (incluindo o formato solicitado, o nome do tópico e o nome do item) e, em seguida, retornar TRUE para permitir que o loop de aviso ou FALSE o negue.

Após um loop de aviso ter sido estabelecido, o aplicativo servidor deve chamar a função DdePostAdvise sempre que o valor do item associado ao nome do item solicitado mudar. Essa chamada resulta em uma transação de XTYP_ADVREQ sendo enviada para a função de retorno de chamada DDE do próprio servidor. A função de retorno de chamada DDE do servidor deve retornar um identificador de dados que identifique o novo valor do item de dados. Em seguida, o DDEML notifica o cliente de que o item especificado foi alterado enviando a transação XTYP_ADVDATA para a função de retorno de chamada DDE do cliente.

Se o cliente solicitou um hot advise loop, o DDEML passa o identificador de dados para o item alterado para o cliente durante a transação XTYP_ADVDATA. Caso contrário, o cliente pode enviar uma transação XTYP_REQUEST para obter o identificador de dados.

É possível que um servidor envie atualizações mais rapidamente do que um cliente pode processar os novos dados. A velocidade das atualizações pode ser um problema para um cliente que deve executar longas operações de processamento nos dados. Nesse caso, o cliente deve especificar o sinalizador de XTYPF_ACKREQ quando solicitar um loop de aconselhamento. Esse sinalizador faz com que o servidor aguarde que o cliente reconheça que recebeu e processou um item de dados antes de enviar o próximo item de dados. Os loops de aviso que são estabelecidos com o sinalizador XTYPF_ACKREQ são mais robustos com servidores rápidos, mas ocasionalmente podem perder atualizações. Os loops de aviso estabelecidos sem o sinalizador XTYPF_ACKREQ são garantidos para não perder atualizações, desde que o cliente acompanhe o servidor.

Um cliente pode encerrar um loop de aviso especificando o tipo de transação XTYP_ADVSTOP em uma chamada para DdeClientTransaction.

Se um servidor não suportar loops de aconselhamento, ele deve especificar o sinalizador de filtro de CBF_FAIL_ADVISES na funçãoDdeInitialize. Esse sinalizador impede que o DDEML envie as transações XTYP_ADVSTART e XTYP_ADVSTOP para o servidor.

Executar transação

Um cliente pode usar a transação XTYP_EXECUTE para fazer com que um servidor execute um comando ou uma série de comandos.

Para executar um comando de servidor, o cliente primeiro cria um buffer que contém uma cadeia de caracteres de comando para o servidor executar e, em seguida, passa um ponteiro para o buffer ou um identificador de dados identificando o buffer quando ele chama DdeClientTransaction. Outros parâmetros necessários incluem o identificador de conversa, o identificador de cadeia de caracteres de nome de item, a especificação de formato e o tipo de transação XTYP_EXECUTE. Um aplicativo que cria um identificador de dados para passar dados de execução deve especificar NULL para o parâmetro hszItem da funçãoDdeCreateDataHandle e zero para o parâmetro uFmt.

O DDEML passa a transação XTYP_EXECUTE para a função de retorno de chamada DDE do servidor e especifica o nome do formato, identificador de conversa, nome do tópico e identificador de dados que identifica a cadeia de comando. Se o servidor suportar o comando, ele deve usar a funçãoDdeAccessDatapara obter um ponteiro para a cadeia de comando, executar o comando e, em seguida, retornar DDE_FACK. Se o servidor não suportar o comando ou não puder concluir a transação, ele deverá retornar DDE_FNOTPROCESSED. O servidor deve retornar DDE_FBUSY se estiver muito ocupado para concluir a transação.

Em geral, a função de retorno de chamada de um servidor deve processar a transação de XTYP_EXECUTE antes de retornar com as seguintes exceções:

  1. Quando o comando passado com a transação XTYP_EXECUTE solicita que o servidor seja encerrado, o servidor não deve ser encerrado até que sua função de retorno de chamada retorne do processamento XTYP_EXECUTE.
  2. Se o servidor precisar executar uma operação, como processar uma caixa de diálogo ou uma transação DDE que possa causar problemas de recursão DDEML, o servidor deverá retornar o código de retorno CBR_BLOCK para bloquear a transação de execução, executar a operação e, em seguida, retomar o processamento da transação de execução.

Quando DdeClientTransaction retorna, o cliente pode usar o parâmetro lpdwResult para acessar o sinalizador de status da transação. Se o sinalizador estiver DDE_FBUSY, o cliente deve enviar a transação novamente mais tarde.

Se um servidor não suportar a transação XTYP_EXECUTE, ele deve especificar o sinalizador de filtro CBF_FAIL_EXECUTES na funçãoDdeInitialize. Isso impede que o DDEML envie a transação para o servidor.

Transações síncronas e assíncronas

Um cliente pode enviar transações síncronas ou assíncronas. Em uma transação síncrona, o cliente especifica um valor de tempo limite que indica a quantidade máxima de tempo que aguardará para que o servidor processe a transação. DdeClientTransaction não retorna até que o servidor processe a transação, a transação falhe ou o valor de tempo limite expire. O cliente especifica o valor de tempo limite quando chama DdeClientTransaction.

Durante uma transação síncrona, o cliente entra em um loop modal enquanto aguarda que a transação seja processada. O cliente ainda pode processar a entrada do usuário, mas não pode enviar outra transação síncrona até que DdeClientTransaction retorne.

Um cliente envia uma transação assíncrona especificando o sinalizador TIMEOUT_ASYNC em DdeClientTransaction. A função retorna após o início da transação, passando um identificador de transação para o cliente. Quando o servidor termina de processar a transação assíncrona, o DDEML envia uma transação XTYP_XACT_COMPLETE para o cliente. Um dos parâmetros que o DDEML passa para o cliente durante a transação XTYP_XACT_COMPLETE é o identificador da transação. Ao comparar esse identificador de transação com o identificador retornado por DdeClientTransaction, o cliente identifica qual transação assíncrona o servidor terminou de processar.

Um cliente pode usar a função DdeSetUserHandle como uma ajuda no processamento de uma transação assíncrona. Essa função possibilita que um cliente associe um valor definido pelo aplicativo a um identificador de conversa e a um identificador de transação. O cliente pode usar a função deDdeQueryConvInfodurante a transação de XTYP_XACT_COMPLETE para obter o valor definido pelo aplicativo. Devido a essa função, um aplicativo não precisa manter uma lista de identificadores de transação ativos.

Quando um cliente conclui com êxito uma solicitação de dados usando uma transação síncrona, o DDEML não tem como saber quando o cliente terminou de usar os dados recebidos. O aplicativo cliente deve passar o identificador de dados recebidos para a funçãoDdeFreeDataHandle, notificando o DDEML de que o identificador não será mais usado. Os identificadores de dados retornados por transações síncronas são efetivamente de propriedade do cliente.

Se um servidor não processar uma transação assíncrona em tempo hábil, o cliente poderá abandonar a transação chamando a funçãoDdeAbandonTransaction. O DDEML libera todos os recursos associados à transação e descarta os resultados da transação quando o servidor termina de processá-la. Um tempo limite durante uma transação síncrona efetivamente cancela a transação.

O método de transação assíncrona é fornecido para aplicativos que devem enviar um alto volume de transações DDE e, ao mesmo tempo, executar uma quantidade substancial de processamento, como a execução de cálculos. O método assíncrono também é útil em aplicativos que devem parar de processar transações DDE temporariamente para que possam concluir outras tarefas sem interrupção. Na maioria das outras situações, um aplicativo deve usar o método síncrono.

As transações síncronas são mais simples de manter e são mais rápidas do que as transações assíncronas. No entanto, apenas uma transação síncrona pode ser executada de cada vez, enquanto muitas transações assíncronas podem ser executadas simultaneamente. Com transações síncronas, um servidor lento pode fazer com que um cliente permaneça ocioso enquanto aguarda uma resposta. Além disso, as transações síncronas fazem com que o cliente entre em um loop modal que pode ignorar a filtragem de mensagens no próprio loop de mensagens do aplicativo.

Se o cliente tiver instalado um procedimento de gancho para filtrar mensagens (ou seja, especificado o tipo de gancho WH_MSGFILTER em uma chamada para a funçãoSetWindowsHookEx), uma transação síncrona não fará com que o sistema ignore o procedimento de gancho. Quando um evento de entrada ocorre enquanto o cliente aguarda o término de uma transação síncrona, o procedimento de gancho recebe um código de gancho MSGF_DDEMGR. O principal perigo de usar um loop modal de transação síncrona é que um loop modal criado por uma caixa de diálogo pode interferir em seu funcionamento. Transações assíncronas devem sempre ser usadas quando o DDEML está sendo usado por uma DLL.

Controlo de Transações

Um aplicativo pode suspender transações para sua função de retorno de chamada DDE as transações associadas a um identificador de conversa específico ou todas as transações, independentemente do identificador de conversa. Esse recurso é útil quando um aplicativo recebe uma transação que requer processamento demorado. Nesse caso, o aplicativo pode retornar o código de retorno CBR_BLOCK para suspender futuras transações associadas ao identificador de conversa da transação, para que o aplicativo fique livre para processar outras conversas.

Quando o processamento for concluído, o aplicativo chamará a função DdeEnableCallback para retomar as transações associadas à conversa suspensa. Chamar DdeEnableCallback faz com que o DDEML reenvie a transação que resultou na suspensão da conversa pelo aplicativo. Portanto, o aplicativo deve armazenar o resultado da transação de tal forma que possa obter e retornar o resultado sem reprocessar a transação.

Um aplicativo pode suspender todas as transações associadas a um identificador de conversa específico especificando o identificador e o sinalizador de EC_DISABLE em uma chamada para DdeEnableCallback. Ao especificar um identificador de NULL, um aplicativo pode suspender todas as transações de todas as conversas.

Quando uma conversa é suspensa, o DDEML salva as transações da conversa em uma fila de transações. Quando o aplicativo reativa a conversa, o DDEML remove as transações salvas da fila e passa cada transação para a função de retorno de chamada apropriada. A capacidade da fila de transações é grande, mas um aplicativo deve reativar uma conversa suspensa o mais rápido possível para evitar a perda de transações.

Um aplicativo pode retomar o processamento de transação normal especificando o sinalizador EC_ENABLEALL em DdeEnableCallback. Para uma retomada mais controlada do processamento de transações, o aplicativo pode especificar o sinalizador EC_ENABLEONE. Esse sinalizador remove uma transação da fila de transações e a passa para a função de retorno de chamada apropriada; Depois que essa transação for processada, todas as conversas serão desativadas novamente.

Se o sinalizador de EC_ENABLEONE e um identificador de conversa forem especificados na chamada para DdeEnableCallback , somente essa conversa será bloqueada após a transação ter sido processada. Se um identificador de conversação de NULL for especificado, todas as conversas serão bloqueadas após uma transação ter sido processada em qualquer conversa.

Classes de transação

O DDEML tem quatro classes de transações. Cada classe é identificada por uma constante que começa com o prefixo XCLASS_. As classes são definidas no arquivo de cabeçalho DDEML. O valor da classe é combinado com o valor do tipo de transação e é passado para a função de retorno de chamada DDE do aplicativo de recebimento.

A classe de uma transação determina o valor de retorno que uma função de retorno de chamada deve retornar se processar a transação. Os seguintes valores de retorno e tipos de transação estão associados a cada uma das quatro classes de transação.

Classe Valor de retorno Transação
XCLASS_BOOL VERDADEIRO ou FALSO XTYP_ADVSTART
XTYP_CONNECT
XCLASS_DATA Um identificador de dados, o código de retorno CBR_BLOCK ou NULL XTYP_ADVREQ
XTYP_REQUEST
XTYP_WILDCONNECT
XCLASS_FLAGS Um sinalizador de transação: DDE_FACK, DDE_FBUSY ou DDE_FNOTPROCESSED XTYP_ADVDATA
XTYP_EXECUTE
XTYP_POKE
XCLASS_NOTIFICATION Nenhum XTYP_ADVSTOP
XTYP_CONNECT_CONFIRM
XTYP_DISCONNECT
XTYP_ERROR
XTYP_REGISTER
XTYP_UNREGISTER
XTYP_XACT_COMPLETE

Tipos de transação

Cada tipo de transação DDE tem um recetor e uma atividade associada que faz com que o DDEML gere cada tipo.

Tipo de transação Recetor Causa
XTYP_ADVDATA Cliente Um servidor respondeu a uma transação de XTYP_ADVREQ retornando um identificador de dados.
XTYP_ADVREQ Servidor Um servidor chamado função DdePostAdvise indicando que o valor de um item de dados em um loop de aviso havia sido alterado.
XTYP_ADVSTART Servidor Um cliente especificou o tipo de transação XTYP_ADVSTART em uma chamada para a funçãoDdeClientTransaction.
XTYP_ADVSTOP Servidor Um cliente especificou o tipo de transação XTYP_ADVSTOP em uma chamada para DdeClientTransaction.
XTYP_CONNECT Servidor Um cliente chamou a funçãoDdeConnect e especificou um nome de serviço e um nome de tópico suportados pelo servidor.
XTYP_CONNECT_CONFIRM Servidor O servidor retornou TRUE em resposta a uma transação XTYP_CONNECT ou XTYP_WILDCONNECT.
XTYP_DISCONNECT Cliente/Servidor Um parceiro em uma conversa chamada DdeDisconnect função, fazendo com que ambos os parceiros recebam essa transação.
XTYP_ERROR Cliente/Servidor Ocorreu um erro crítico. A DDEML pode não ter recursos suficientes para continuar.
XTYP_EXECUTE Servidor Um cliente especificou o tipo de transação XTYP_EXECUTE em uma chamada para DdeClientTransaction.
XTYP_MONITOR Aplicação de monitorização DDE Ocorreu um evento DDE no sistema. Para obter mais informações sobre aplicativos de monitoramento DDE, consulte Monitoring Applications.
XTYP_POKE Servidor Um cliente especificou o tipo de transação XTYP_POKE em uma chamada para DdeClientTransaction.
XTYP_REGISTER Cliente/Servidor Um aplicativo de servidor usou a função DdeNameService para registrar um nome de serviço.
XTYP_REQUEST Servidor Um cliente especificou o tipo de transação XTYP_REQUEST em uma chamada para DdeClientTransaction.
XTYP_UNREGISTER Cliente/Servidor Um aplicativo de servidor usado DdeNameService para cancelar o registro de um nome de serviço.
XTYP_WILDCONNECT Servidor Um cliente chamado DdeConnect ou função DdeConnectList, especificando NULL para o nome do serviço, o nome do tópico ou ambos.
XTYP_XACT_COMPLETE Cliente Uma transação assíncrona, enviada quando o cliente especificou o sinalizador de TIMEOUT_ASYNC em uma chamada para DdeClientTransaction, foi concluída.