AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 25161
Accepted
Centurion
Centurion
Asked: 2012-10-01 04:13:56 +0800 CST2012-10-01 04:13:56 +0800 CST 2012-10-01 04:13:56 +0800 CST

Quais são os casos reais de uso do enfileiramento avançado da Oracle?

  • 772

Quais são os casos em que o enfileiramento avançado da Oracle é o mecanismo preferencial para implementar os requisitos funcionais? Por exemplo, a transferência de dinheiro da conta bancária A para a conta bancária B pode teoricamente ser considerada como duas operações diferentes e pode ser implementada separadamente - primeiro, enfileirar a transferência de dinheiro da conta A (atualizar) e depois enfileirar a transferência de dinheiro para a conta B (atualizar) . No entanto, é óbvio que não pode ser feito assim porque essas duas operações devem ser feitas em uma operação consistente - na transação.

Talvez o enfileiramento avançado deva ser considerado apenas ao desenvolver procedimentos/funções armazenados que executam alguma lógica que é feita internamente (fazendo operações DML e chamando outro proc/fnc armazenado local) e externamente (chamando alguns webservices). Ao usar essas chamadas para webservices, não podemos envolver tudo em uma transação consistente, então a única maneira é usar algum mecanismo de enfileiramento ...

Quaisquer exemplos detalhados da vida real seriam apreciados.

O que estou curioso não são os detalhes da tecnologia em si, mas sim quais são os casos reais de uso dessas mensagens, porque nunca fiz isso antes. Tipo, por que preciso passar alguns dados (carga útil da mensagem)?

oracle
  • 5 5 respostas
  • 26175 Views

5 respostas

  • Voted
  1. Chris Travers
    2012-10-01T18:51:53+08:002012-10-01T18:51:53+08:00

    Não estou tão familiarizado com o Oracle como estou com o Postgres. No entanto, vou lhe dizer onde vejo abordagens de enfileiramento como esta como ideais (como o autor de pg_message_queue ): permitir que transações de banco de dados tenham efeitos colaterais não transacionais com custo mínimo de complexidade. Um exemplo simples é "quando realizamos uma transação dizendo que enviamos uma peça, vamos enviar um e-mail notificando o cliente".

    Você poderia fazer isso sem o Oracle AQ, mas o Oracle AQ provavelmente tornará isso mais simples. O fator chave é que isso permite que você enfileira a mensagem de forma que fique visível no commit e tenha a mensagem que será a base de um email assim que a transação do banco de dados for confirmada e não antes. Se você tentar enviar a mensagem de dentro da transação, receberá vários casos de falha desagradáveis:

    1. Se a mensagem não for enviada, devemos abortar a transação?
    2. Se a mensagem for enviada e a transação for revertida posteriormente, como cancelaremos o envio do e-mail? Não podemos.

    Outro exemplo pode ser aplicativos fracamente acoplados, integrados em uma fila de mensagens. Cada aplicativo pode ser executado sem conhecimento do outro, mas quando as transações são confirmadas, as mensagens são enviadas para o outro. Se eles não puderem ser entregues imediatamente, não há problema. Vamos processá-los quando pudermos.

    Portanto, o básico é que há muitos casos em que você deseja centralizar a lógica em torno do banco de dados, onde não pode realmente fazer tudo corretamente em uma única transação. Ser capaz de enviar mensagens para outros componentes no db commit é realmente útil.

    E com certeza você poderia construir tudo sozinho sem AQ. Mas isso já foi construído para você.

    Edit: Eu reli os documentos da Oracle aqui e eles são irremediavelmente confusos, então não o culpo por sua confusão aqui. Se eu já não estivesse um pouco familiarizado com os tipos de coisas sobre as quais eles estavam falando, não tenho certeza se seria capaz de segui-los. Agora tenho 100% de certeza de que minha resposta está no alvo.

    • 7
  2. Best Answer
    kevinskio
    2012-10-02T17:14:04+08:002012-10-02T17:14:04+08:00

    Eu uso AQ para

    • transações entre bancos de dados
    • implementar regras de negócios que, de outra forma, precisariam ser implementadas usando gatilhos (ou seja, as ações devem ser executadas na mesma tabela que inicia a ação)

    Usando uma fila, você pode fazer estas coisas:

    • uma transação pode ocorrer na ordem que você deseja, mas não instantaneamente. por exemplo, inserir em um banco de dados, copiar o mesmo registro para outro banco de dados
    • a segunda transação agora é independente da primeira, mas você ainda tem consistência. por exemplo, somente se a primeira inserção for bem-sucedida a segunda transação AQ ocorrerá e se a segunda transação ocorrer em outro banco de dados isso só acontecerá se o segundo banco de dados estiver pronto para receber

    Aqui estão mais informações sobre como eu uso AQ entre bancos de dados. Eu não sou um especialista e peguei a maior parte do código da Internet. A documentação do Oracle é longa, mas realmente não me ajudou.

    Primeiro crie a fila:

    BEGIN
      SYS.DBMS_AQADM.CREATE_QUEUE_TABLE
      (
        QUEUE_TABLE           =>        'QT_NEW_CASE'
       ,QUEUE_PAYLOAD_TYPE    =>        'FILE_ACTION'
       ,COMPATIBLE            =>        '8.1'
       ,STORAGE_CLAUSE        =>        '
                                         TABLESPACE USERS
                                         PCTUSED    0
                                         PCTFREE    10
                                         INITRANS   1
                                         MAXTRANS   255
                                         STORAGE    (
                                                     INITIAL          64K
                                                     NEXT             1M
                                                     MINEXTENTS       1
                                                     MAXEXTENTS       UNLIMITED
                                                     PCTINCREASE      0
                                                     BUFFER_POOL      DEFAULT
                                                    )'
       ,SORT_LIST             =>        'ENQ_TIME'
       ,MULTIPLE_CONSUMERS    =>         FALSE
       ,MESSAGE_GROUPING      =>         0
       ,SECURE                =>         FALSE
       );
    End;
    

    No banco de dados de origem:

    CREATE OR REPLACE TYPE FILE_ACTION                                                                                                                                                       AS OBJECT
    (    ACTION VARCHAR2(20),
         CASE_ID NUMBER(10),
         OTHER VARCHAR2(20)
    );
    

    A ação é reconhecidamente grosseira, mas versátil. Os requisitos eram afunilar as alterações de várias tabelas para outro banco de dados onde era necessário processamento adicional sem tocar no código do aplicativo. Uma chamada típica é para um pacote de um gatilho, outro procedimento ou trabalho.

    queue_util.add_file ('CLOSE', v_case_id,:NEW.ID);
    

    Dentro do pacote

       PROCEDURE add_file_to_queue (action_in      IN VARCHAR2,
                                    d_case_id_in   IN NUMBER,
                                    d_other_in     IN VARCHAR2:= NULL)
       IS
          /******************************************************************************
          PURPOSE: when there is a change to a file (create, closed or reopen)  add the change to the queue of changes 
         ******************************************************************************/
          queue_options        SYS.DBMS_AQ.enqueue_options_t;
          message_properties   SYS.DBMS_AQ.message_properties_t;
          message_id           RAW (16);
          my_message           file_action;
          err_text             VARCHAR2 (2000);
          PRAGMA AUTONOMOUS_TRANSACTION;
       BEGIN
          my_message := file_action (action_in, d_case_id_in, d_other_in);
          DBMS_AQ.enqueue (queue_name           => 'NEW_CASE_QUEUE',
                           enqueue_options      => queue_options,
                           message_properties   => message_properties,
                           payload              => my_message,
                           msgid                => message_id);
    
          IF g_debugging
          THEN
            ;
          --insert debugging info if g_debugging is true
          END IF;
    
          COMMIT;
       EXCEPTION
          WHEN NO_DATA_FOUND
          THEN
             err_text := SQLERRM;
             --logging error to another table
    
          WHEN OTHERS
          THEN
             err_text := SQLERRM;
             --more logging
       END add_file_to_queue;
    

    --e tirando mensagens da fila

       PROCEDURE send_from queue (case_id_in IN NUMBER := NULL)
       IS
          /******************************************************************************
          PURPOSE:get the list of file changes and send them out
          *****************************************************************************/
          queue_options                DBMS_AQ.dequeue_options_t;
          message_properties           DBMS_AQ.message_properties_t;
          message_id                   file_action;
          v_file                       VARCHAR2 (20);
          v_case_id                    NUMBER (10);
          v_filename                   VARCHAR2 (500);
          v_action                     VARCHAR2 (20);
          v_other                      VARCHAR2 (20);
          v_err_id                     INTEGER;
          bad_data_ex EXCEPTION;
          v_err_text                   VARCHAR2 (50);
    
          TYPE cases_cur IS REF CURSOR;
    
          new_cases                    cases_cur;
       BEGIN
          IF case_id_in IS NULL
          THEN
             OPEN new_cases FOR
                  SELECT   qt.msgid
                    FROM   cqt_new_case qt
                ORDER BY   qt.enq_time;
          ELSE
             OPEN new_cases FOR
                  SELECT   qt.msgid
                    FROM   qt_new_case qt
                   WHERE   qt.user_data.case_id = case_id_in
                ORDER BY   qt.enq_time;
          END IF;
    
          --should have added a check here to make sure
          --the other database is up and running
          LOOP
             BEGIN
                FETCH new_cases INTO   message_id;
    
                --reinitialize values to null
                v_case_id := NULL;
                v_filename := NULL;
                v_file := NULL;
                v_action := NULL;
                v_other := NULL;
                --to try and clear all locks
                COMMIT;
                EXIT WHEN new_cases%NOTFOUND;
    
                IF case_id_in IS NOT NULL
                THEN
                   queue_options.deq_condition :=
                      'tab.user_data.case_id = ' || case_id_in;
                END IF;
    
                DBMS_AQ.dequeue (queue_name           => 'NEW_CASE_QUEUE',
                                 dequeue_options      => queue_options,
                                 message_properties   => message_properties,
                                 payload              => my_message,
                                 msgid                => message_id);
                v_case_id := my_message.case_id;
                v_action := my_message.action;
                v_other := my_message.other;
    
                IF v_case_id IS NOT NULL AND v_case_id > 0
                THEN
                   IF g_debugging
                   THEN
                     ;
                   --insert your debugging information
                   END IF;
                --continues on with lengthy data transforms
                --for actions like NEW, CLOSE, REOPEN
    END SEND_FROM_QUEUE;
    

    Eu certamente escreveria isso de forma diferente hoje, mas funciona... O principal problema com o AQ para mim é que eu nunca recebi mensagens de fila para fila entre bancos de dados diferentes. Isso foi descrito como um valor primário para ele. No entanto, ainda gosto de ter a certeza de que a transação inicial pode ser concluída sem levar em consideração o estado do banco de dados de destino. Se a mensagem não for inserida no banco de dados de destino, um erro será registrado e um e-mail será enviado notificando o desenvolvedor.

    • 4
  3. user115543
    2017-01-21T09:58:28+08:002017-01-21T09:58:28+08:00

    Na vida real, o AQ pode ser usado para enviar notificações aos clientes quando uma ação específica é executada no banco de dados.

    Considere um exemplo em que um usuário solicitou a compra de um item. Assim que o pagamento for recebido, um pedido será criado preenchendo a fila com os detalhes. Essa fila terá assinantes para o dono da loja e os aplicativos de mensagens de pagamento.

    Assim, o assinante 1, ou seja, o dono da loja (qualquer notificação a ser enviada ao dono da loja) escolherá a mensagem sobre o item a ser enviado. e outro assinante preparará a notificação sobre o item adquirido, portanto, neste caso, uma vez que a mensagem seja processada pelo assinante, o pedido é marcado como concluído e a mensagem da fila é removida.

    Se durante o processamento do pedido ocorrer algum erro, uma entrada será marcada na fila de exceção e as mensagens da fila de exceção poderão ser processadas posteriormente.

    • 1
  4. Balram Parmar
    2017-12-07T21:58:33+08:002017-12-07T21:58:33+08:00

    Você pode usar o Oracle AQ para vários exemplos da vida real, como usamos -

    1. Ordem de fluxo de pedidos - Temos vários pedidos chegando, que precisam ser processados ​​em um determinado pedido para que o cliente coloque a mensagem de diferentes lugares em momentos diferentes, então apenas enfileiramos a mensagem e obtemos o pedido correto durante o desenfileiramento.
    2. Usamos o Oracle AQ para notificação do fluxo de trabalho completo, ou seja, algum cliente que iniciou/enviou um procedimento para ser executado com sucesso o mesmo é executado pelo agendador, portanto, uma vez que este procedimento termine o processamento, enfileiramos uma mensagem que notifica o cliente que iniciou o procedimento (usando oracle aq pl/sql notificações).
    3. O melhor uso é replicar dados de um banco de dados para outro, você acabou de definir o assinante remoto, então o AQ transferirá os dados de uma fila para outra fila na mesma ordem internamente, isso é chamado de propagação, que também está sendo usado nos fluxos oracle .
    • 1
  5. Larry Lo
    2012-10-01T09:25:41+08:002012-10-01T09:25:41+08:00

    Depende do requisito dos aplicativos da Web e do propósito de usar o Advanced Queueing.

    Acho que existem alternativas como comparar o timestamp que inicia a consulta e, portanto, verificar a prioridade da consulta de transação a ser executada primeiro.

    • 0

relate perguntas

  • Backups de banco de dados no Oracle - Exportar o banco de dados ou usar outras ferramentas?

  • ORDER BY usando prioridades personalizadas para colunas de texto

  • Interface sqlplus confortável? [fechado]

  • Como encontrar as instruções SQL mais recentes no banco de dados?

  • Como posso consultar nomes usando expressões regulares?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve