Fiz uma pergunta sobre a implementação de grupos de conversação em uma configuração do SQL Service Broker que possui vários serviços de usuário se comunicando com o serviço do servidor (processando solicitações de dados xml a serem enviadas para um serviço da Web externo). Mas, como os grupos de conversação não garantem a ordem no processamento, você acha que há algo de errado em usar o mesmo identificador de conversa para todas as solicitações que vão para a mesma fila de destino (garantindo a ordem em que foram enviadas, independentemente da origem) ?
para o segundo plano: como você implementaria grupos de conversação/bloqueio para vários usuários de uma fila do Service Broker?
Como foi mencionado por Rusanu na resposta,
E não se esqueça que a única construção que garante a ordem no SSB é uma conversa. Portanto, se os usuários precisarem enviar lances para A na conversa 1, seguidos de lances para B na conversa 2, não há garantia de que o lance para A será processado depois que o lance para B for processado. A única garantia é que se o usuário 1 enviar dois lances para A, eles serão processados na ordem enviada.
Além disso, se dois usuários diferentes enviarem lances para o produto A, não há garantia da ordem de processamento desses lances. No entanto, se os lances do produto A terminarem no mesmo CG, existe a garantia de que apenas um 'processador thread' verá o lance do usuário 1 e o lance do usuário 2, mas tenha cuidado porque não há garantia de que os lances são apresentados no conjunto de resultados RECEIVE na ordem em que foram recebidos. A RECEIVE apenas garante que:
* all messages in the result set are from the same CG * the messages belonging to a conversation are in order
mas a ordem das conversas no resultado é basicamente aleatória (é orientada pela ordem do identificador de conversa, um GUID).
Como em um leilão real, eu gostaria que os itens da fila fossem processados na ordem em que estão chegando na fila para o usuário A, usuário B e usuário C enviando um "lance" para o mesmo produto. Estou pensando em implementar tudo isso usando os mesmos identificadores de conversa para todas as conversas no mesmo produto.
O que acho que vou tentar até agora:
O mecanismo será o aplicativo do servidor enviar um iniciador de conversa (inicialização) para N conversas para um User_0 (onde N é o número de "canais de conversa multiplexados" que teremos) - armazenamos os identificadores de conversa em uma tabela como esta :
CREATE TABLE ConversationChannelStatus
(ConversationChannel_pk numeric Primary Key, ConversationHandle UNIQUEIDENTIFIER)
USER_A, ao enviar "lances", enviará uma mensagem do User_A Service para o serviço de destino usando os handles de conversa que estão salvos na Tabela ConversationChannelStatus (Indexada por uma chave primária numérica simples, o "ConversationChannels").
É problemático armazenar identificadores de conversa em uma tabela e, em seguida, fazer com que vários serviços do iniciador continuem usando os mesmos identificadores de conversa enquanto enviam mensagens para a fila de destino?
Obrigada.
Atualização: Desculpe, confundi-me com estas palavras, ID da conversa, identificador da conversa. O mesmo identificador de conversa definitivamente não pode ser usado porque é diferente para iniciador e destino. Acho que estou me referindo a tentar usar o mesmo ID de conversa de vários iniciadores para o mesmo destino para tentar manter a ordem na fila de processamento de mensagens provenientes de vários serviços.
Atualização 2: Ainda trabalhando nisso, mas acho que a solução será assim, envolvendo ambos os identificadores de conversação e o conversationgroupid.
- Comece inicializando a conversa N versus o usuário 0 e armazene o ID do grupo de conversação, bem como o identificador de conversa, ambos na tabela de configurações do canal.
- Quando um serviço UserA, UserB, UserC deseja ingressar, o aplicativo do servidor iniciará as N conversas com cada um dos serviços do usuário, usando os identificadores de conversa que armazenamos anteriormente na tabela de configurações do canal.
- Em seguida, os serviços do usuário (os alvos dessa mensagem) receberão essa mensagem e responderão usando os conversationgroupIds da tabela de configurações do canal somente quando o serviço do usuário tiver um "lance" para enviar. Assim, fornecendo uma maneira fácil para o serviço do usuário saber qual ID do grupo de conversação relacionado usar, mantendo a ordem de conversa desejada no servidorAPP Serviço fila de processamento de mensagens dos usuários A, B, C (uma vez que está respondendo a uma conversa específica iniciada por o serviço serverapp). Eu espero que dê certo!
A contenção será o maior problema. Uma conversa garante ordem, mas para que tal garantia seja dada, o verbo SEND deve bloquear o identificador de conversa usado até o final da transação (ou durante a instrução se nenhuma transação explícita for usada). Na verdade, isso significa que apenas uma transação pode enviar um lance no produto A a qualquer momento. Se isso é aceitável ou não depende inteiramente de seus requisitos de negócios.
Os termos: uma conversa tem dois pontos finais, o iniciador e o alvo. Cada conversa tem um ID exclusivo, o
conversation_id
(um guid) que tem o mesmo valor em ambos os terminais (ou seja, ele viaja na rede com as mensagens). Cada endpoint tem seu próprio identificador, oconversation_handle
(novamente, um guid) que você usa com verbos SSB. o identificador é apenas local e nunca viaja com a mensagem. Então você acertou na sua atualização ;)Acho que o que você descreve na Atualização 2 está OK, mas, como sempre, o diabo está nos detalhes. Eu sugiro que você comece a experimentar com código de protótipo e trocar mensagens reais, você terá uma sensação muito melhor quando o vir funcionando.