Usar Mensagens Persistentes com Mensagens Armazenadas no Cloud Object Store

O pacote DBMS_PIPE tem funcionalidade estendida no Autonomous Database para suportar mensagens persistentes, em que as mensagens são armazenadas no Cloud Object Store.

Sobre Mensagens Persistentes com DBMS_PIPE

As mensagens persistentes com DBMS_PIPE permitem que uma ou mais sessões de banco de dados se comuniquem na mesma região ou entre regiões com mensagens armazenadas no Armazenamento de Objetos na Nuvem.

Mensagens persistentes em DBMS_PIPE:

  • Permite que você envie e recupere mensagens muito grandes.

  • Suporta o envio de um grande número de mensagens de pipe.

  • Ofereça suporte ao envio e recebimento de mensagens em um único banco de dados, em vários bancos de dados e em bancos de dados em diferentes regiões.

  • Suporta vários pipes usando o mesmo URI de localização do Cloud Object Store.

Os pipes de mensagens persistentes podem ser criados em qualquer um dos tipos DBMS_PIPE suportados:

  • Tubulação Implícita: Criada automaticamente quando uma mensagem é enviada com um nome de pipe desconhecido usando a função DBMS_PIPE.SEND_MESSAGE.
  • Tubulação Explícita: Criada usando a função DBMS_PIPE.CREATE_PIPE com um nome de pipe especificado pelo usuário.
  • Pipe Público: Acessível por qualquer usuário com a permissão EXECUTE no pacote DBMS_PIPE.
  • Pipe Privado: Acessível por sessões com o mesmo usuário do criador do pipe.
Observação

A Oracle recomenda criar um pipe explícito antes de enviar ou receber mensagens com mensagens persistentes. A criação de um pipe explícito com DBMS_PIPE.CREATE_PIPE garante que o pipe seja criado com as permissões de acesso desejadas, públicas ou privadas (definindo o parâmetro private).

Veja a seguir o workflow geral de DBMS_PIPE com mensagens persistentes:

A seguir, descrição de database-pipe-persistent-messaging.eps
Descrição da ilustração database-pipe-persistent-messaging.eps

Os aplicativos existentes que usam DBMS_PIPE podem continuar operando com alterações mínimas. Você pode configurar aplicativos existentes que usam DBMS_PIPE com um objeto de credencial e um URI de local usando um trigger de log-on ou usando alguma outra rotina de inicialização. Depois de definir a credencial DBMS_PIPE e o URI de local, nenhuma outra alteração será necessária para usar mensagens persistentes. Todo o uso subsequente do pipe armazena as mensagens no Armazenamento de Objetos na Nuvem em vez de na memória do banco de dados. Isso permite que você altere o método de armazenamento para mensagens do Cloud Object Storage na memória para persistente, com alterações mínimas.

Visão Geral e Recursos de Mensagens Persistentes

Recursos do DBMS_PIPE usando mensagens persistentes:

  • As mensagens podem ser enviadas e recuperadas em várias instâncias do Autonomous Database na mesma região ou entre regiões.

  • As mensagens persistentes são garantidas para serem escritas ou lidas por exatamente um processo. Isso evita a inconsistência do conteúdo da mensagem devido a gravações e leituras simultâneas. Usando um pipe de mensagens persistente, DBMS_PIPE permite que apenas uma operação, enviando uma mensagem ou uma mensagem de recebimento, fique ativa em um determinado momento. No entanto, se uma operação não for possível devido a uma operação em andamento, o processo repetirá periodicamente até que o valor timeout seja atingido.

  • DBMS_PIPE usa DBMS_CLOUD para acessar o Cloud Object Store. As mensagens podem ser armazenadas em qualquer Armazenamento de Objetos na Nuvem suportado. Consulte DBMS_CLOUD Formatos de URI para obter mais informações.

  • O DBMS_PIPE usa DBMS_CLOUD para acessar o Cloud Object Store e todos os tipos de credenciais suportados estão disponíveis:

DBMS_PIPE Autorização e Segurança de Privilégios

Os procedimentos DBMS_PIPE são executados com direitos do chamador. Os pipes privados pertencem ao usuário atual e um pipe privado criado por um usuário só pode ser usado pelo mesmo usuário. Isso se aplica a pipes na memória e a pipes de mensagens persistentes em que as mensagens são armazenadas no Cloud Object Store. O envio e o recebimento de mensagens são executados no esquema do chamador.

Usando pipes privados, nos quais as mensagens são armazenadas no Armazenamento de Objetos na Nuvem, é necessário um objeto de credencial para autenticação com o armazenamento de Objetos na Nuvem identificado pelo parâmetro location_uri. O usuário que faz a chamada deve ter o privilégio EXECUTE no objeto de credencial especificado com o parâmetro credential_name usado para acessar o Armazenamento de Objetos.

Para usar um pipe público, o usuário, a sessão do banco de dados, deve ter o privilégio de execução em DBMS_PIPE. Para um pipe público usando mensagens persistentes e armazenando mensagens no Cloud Object Store, o usuário, a sessão de banco de dados, deve ter privilégio de execução em DBMS_CLOUD e executar privilégio no objeto de credencial (ou você pode criar um objeto de credencial que tenha permissão para acessar o URI de local que contém a mensagem).

DBMS_PIPE Limitação

O pacote DBMS_PIPE não suporta o envio de mensagens entre bancos de dados que usam conjuntos de caracteres diferentes. Por exemplo, se você tiver uma instância do Autonomous Database que use AL32UTF8 e outra que use WE8MSWIN1252, não poderá enviar mensagens com DBMS_PIPE entre esses dois bancos de dados. Nesse caso, o sistema gerará o erro ORA-12704 se você tentar enviar mensagens com DBMS_PIPE entre esses dois bancos de dados.

Consulte Selecionar um Conjunto de Caracteres para o Autonomous Database para obter mais informações.

Criar um Pipe Persistente Explícito e Enviar uma Mensagem

Descreve as etapas para criar um pipe persistente com um nome de pipe especificado (Tubulação Explícita).

  1. Armazene suas credenciais de armazenamento de objetos usando o procedimento DBMS_CLOUD.CREATE_CREDENTIAL. Por exemplo:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'my_persistent_pipe_cred',
        username => 'adb_user@example.com',
        password => 'password'
      );
    END;
    /

    Esta operação armazena as credenciais no banco de dados em um formato criptografado. Você pode usar qualquer nome para o nome da credencial. Observe que essa etapa só é necessária uma vez, a menos que suas credenciais do armazenamento de objetos sejam alteradas. Depois de armazenar as credenciais, você poderá usar o mesmo nome de credencial para acessar o Cloud Object Store para enviar e receber mensagens com DBMS_PIPE.

    Para obter informações detalhadas sobre os parâmetros, consulte CREATE_CREDENTIAL Procedure. Para o Oracle Cloud Infrastructure Object Storage, é necessário que a credencial use autenticação nativa do Oracle Cloud Infrastructure.

    A criação de uma credencial para acessar o Oracle Cloud Infrastructure Object Store não será necessária se você ativar as credenciais do controlador de recursos. Para obter mais informações, consulte Usar o Controlador de Recursos para Acessar Recursos do Oracle Cloud Infrastructure.

    Observação

    Algumas ferramentas como SQL*Plus e SQL Developer usam o E comercial (&) como caractere especial. Se você tiver o caractere E comercial em sua senha, use o comando SET DEFINE OFF nessas ferramentas, conforme mostrado no exemplo, para desativar o caractere especial e fazer com que a credencial seja criada corretamente.
  2. Crie um pipe explícito para enviar e recuperar mensagens. Por exemplo, crie um pipe chamado ORDER_PIPE.
    DECLARE
      r_status INTEGER;
    BEGIN
        r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE');
    END;
    /

    Consulte CREATE_PIPE Função para obter mais informações.

  3. Verifique se o pipe foi criado.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 
  4. Use procedimentos DBMS_PIPE para definir a credencial de acesso padrão e o URI de local para armazenar mensagens persistentes no Cloud Object Store.
    BEGIN
        DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred');
        DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); 
    END;
    /

    Esses procedimentos definem o nome da credencial padrão e o URI de localização padrão para uso com procedimentos DBMS_PIPE.

    Se você usar o Oracle Cloud Infrastructure Object Storage para armazenar mensagens, poderá usar URIs Nativos do Oracle Cloud Infrastructure ou URIs Swift. No entanto, o URI do local e a credencial devem corresponder ao tipo da seguinte forma:

    • Se você usar um formato de URI nativo para acessar o Oracle Cloud Infrastructure Object Storage, deverá usar a autenticação de Chaves de Assinatura Nativas do Oracle Cloud Infrastructure no objeto de credencial.

    • Se você usar o formato de URI Swift para acessar o Oracle Cloud Infrastructure Object Storage, deverá usar uma autenticação de token de autenticação no objeto de credencial.

    Consulte Procedimento SET_CREDENTIAL_NAME e Procedimento SET_LOCATION_URI para obter mais informações.

  5. Empacote e envie uma mensagem no pipe.
    DECLARE
      l_result INTEGER;
      l_date   DATE;
    BEGIN
        l_date := sysdate;
        DBMS_PIPE.PACK_MESSAGE(l_date);         -- date of order
        DBMS_PIPE.PACK_MESSAGE('C123');         -- order number
        DBMS_PIPE.PACK_MESSAGE(5);              -- number of items in order
        DBMS_PIPE.PACK_MESSAGE('Printers');     -- type of item in order
    
     
        l_result := DBMS_PIPE.SEND_MESSAGE(
                        pipename => 'ORDER_PIPE',
                        credential_name => DBMS_PIPE.GET_CREDENTIAL_NAME,
                        location_uri => DBMS_PIPE.GET_LOCATION_URI);
         
        IF l_result = 0 THEN
            DBMS_OUTPUT.put_line('DBMS_PIPE sent order successfully');
        END IF;
     
    END;
    /

    Consulte Procedimentos PACK_MESSAGE e Função SEND_MESSAGE para obter mais informações.

Recuperar uma Mensagem Persistente no Mesmo Banco de Dados

Descreve as etapas para recuperar uma mensagem persistente de um pipe explícito na mesma instância do Autonomous Database (a instância para a qual a mensagem foi enviada).

Em uma instância do Autonomous Database, você pode receber mensagens enviadas para um pipe de outra sessão. Os procedimentos DBMS_PIPE são procedimentos de direitos do chamador e executados como o usuário chamado atual.

Os pipes privados pertencem ao usuário atual que cria o pipe. Os pipes privados só podem ser acessados pelo mesmo usuário que criou o pipe. Isso se aplica a pipes que usam mensagens na memória e a pipes que usam mensagens persistentes com mensagens armazenadas no Cloud Object Store.

Os pipes públicos podem ser acessados por qualquer sessão do banco de dados que tenha privilégio de execução em DBMS_PIPE. Isso se aplica a pipes que usam mensagens na memória e a pipes que usam mensagens persistentes com mensagens armazenadas no Cloud Object Store.

  1. Verifique se o pipe foi criado.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 

    Quando você estiver na mesma instância do Autonomous Database e o pipe existir, não será necessário executar DBMS_PIPE.CREATE_PIPE antes de receber uma mensagem. Isso se aplica quando o pipe foi criado na mesma instância, conforme mostrado em Criar um Pipe Persistente Explícito e Enviar uma Mensagem.

  2. Receba uma mensagem do pipe.
    DECLARE
        message1  DATE;
        message2  VARCHAR2(100);
        message3  INTEGER;
        message4  VARCHAR2(100);
        l_result  INTEGER;
    
    BEGIN
    
        DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred');
        DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); 
        l_result := DBMS_PIPE.RECEIVE_MESSAGE (
                      pipename => 'ORDER_PIPE',
                      timeout  => DBMS_PIPE.MAXWAIT,
                      credential_name => DBMS_PIPE.GET_CREDENTIAL_NAME,
                      location_uri => DBMS_PIPE.GET_LOCATION_URI);
     
        IF l_result = 0 THEN
            DBMS_PIPE.unpack_message(message1);
            DBMS_PIPE.unpack_message(message2);
            DBMS_PIPE.unpack_message(message3);
            DBMS_PIPE.unpack_message(message4);
     
            DBMS_OUTPUT.put_line('Order Received Successfully On: ' || TO_CHAR(sysdate, 'dd-mm-yyyy hh24:mi:ss'));
            DBMS_OUTPUT.put_line('Date of Order: ' || message1);
            DBMS_OUTPUT.put_line('Order Number: ' || message2);
            DBMS_OUTPUT.put_line('Number of Items In Order: ' || message3);
            DBMS_OUTPUT.put_line('Item Type in Order: ' || message4);
        END IF;
     
    END;
    /

    Quando você está na mesma instância do Autonomous Database, a credencial já existe e não é necessário executar DBMS_CLOUD.CREATE_CREDENTIAL para receber uma mensagem. Isso se aplica quando o pipe foi criado na mesma instância, conforme mostrado em Criar um Pipe Persistente Explícito e Enviar uma Mensagem.

Consulte Procedimento SET_CREDENTIAL_NAME e Procedimento SET_LOCATION_URI para obter mais informações.

Consulte RECEIVE_MESSAGE Função para obter mais informações.

Recuperar uma Mensagem Persistente Criando um Pipe em um Banco de Dados Diferente

Descreve as etapas para recuperar uma mensagem persistente armazenada no Cloud Object Store com um pipe explícito em uma instância do Autonomous Database diferente da instância que enviou a mensagem.

  1. Armazene suas credenciais de armazenamento de objetos usando o procedimento DBMS_CLOUD.CREATE_CREDENTIAL. Por exemplo:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'my_persistent_pipe_cred',
        username => 'adb_user@example.com',
        password => 'password'
      );
    END;
    /

    Esta operação armazena as credenciais no banco de dados em um formato criptografado. Você pode usar qualquer nome para o nome da credencial. Observe que essa etapa só é necessária uma vez, a menos que suas credenciais do armazenamento de objetos sejam alteradas. Depois de armazenar as credenciais, você poderá usar o mesmo nome de credencial para acessar o Armazenamento de Objetos na Nuvem para enviar e receber mensagens com DBMS_PIPE.

    Para obter informações detalhadas sobre os parâmetros, consulte CREATE_CREDENTIAL Procedure.

    A criação de uma credencial para acessar o Oracle Cloud Infrastructure Object Store não será necessária se você ativar as credenciais do controlador de recursos. Para obter mais informações, consulte Usar o Controlador de Recursos para Acessar Recursos do Oracle Cloud Infrastructure.

    Observação

    Algumas ferramentas como SQL*Plus e SQL Developer usam o E comercial (&) como caractere especial. Se você tiver o caractere E comercial em sua senha, use o comando SET DEFINE OFF nessas ferramentas, conforme mostrado no exemplo, para desativar o caractere especial e fazer com que a credencial seja criada corretamente.
  2. Crie um pipe explícito com o mesmo nome do pipe que enviou a mensagem. Por exemplo, crie um pipe chamado ORDER_PIPE.
    DECLARE
      r_status INTEGER;
    BEGIN
        r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE');
    END;
    /
  3. Verifique se o pipe foi criado.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 
  4. Use procedimentos DBMS_PIPE para definir a credencial de acesso padrão e o URI de local do Armazenamento de Objetos para que DBMS_PIPE possa acessar a mensagem persistente.
    BEGIN
        DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred');
        DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); 
    END;
    /

    Esses procedimentos definem o nome da credencial padrão e o URI de localização padrão para uso com procedimentos DBMS_PIPE.

    Se você usar o Oracle Cloud Infrastructure Object Storage para armazenar mensagens, poderá usar URIs Nativos do Oracle Cloud Infrastructure ou URIs Swift. No entanto, o URI do local e a credencial devem corresponder ao tipo da seguinte forma:

    • Se você usar um formato de URI nativo para acessar o Oracle Cloud Infrastructure Object Storage, deverá usar a autenticação de Chaves de Assinatura Nativas do Oracle Cloud Infrastructure no objeto de credencial.

    • Se você usar o formato de URI Swift para acessar o Oracle Cloud Infrastructure Object Storage, deverá usar uma autenticação de token de autenticação no objeto de credencial.

    Consulte Procedimento SET_CREDENTIAL_NAME e Procedimento SET_LOCATION_URI para obter mais informações.

  5. Receba uma mensagem do pipe persistente.
    DECLARE
        message1  DATE;
        message2  VARCHAR2(100);
        message3  INTEGER;
        message4  VARCHAR2(100);
        l_result  INTEGER;
    
    BEGIN
    
        DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred');
        DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); 
        l_result := DBMS_PIPE.RECEIVE_MESSAGE (
                      pipename => 'ORDER_PIPE',
                      timeout  => DBMS_PIPE.MAXWAIT,
                      credential_name => DBMS_PIPE.GET_CREDENTIAL_NAME,
                      location_uri => DBMS_PIPE.GET_LOCATION_URI);
     
        IF l_result = 0 THEN
            DBMS_PIPE.unpack_message(message1);
            DBMS_PIPE.unpack_message(message2);
            DBMS_PIPE.unpack_message(message3);
            DBMS_PIPE.unpack_message(message4);
     
            DBMS_OUTPUT.put_line('Order Received Successfully On: ' || TO_CHAR(sysdate, 'dd-mm-yyyy hh24:mi:ss'));
            DBMS_OUTPUT.put_line('Date of Order: ' || message1);
            DBMS_OUTPUT.put_line('Order Number: ' || message2);
            DBMS_OUTPUT.put_line('Number of Items In Order: ' || message3);
            DBMS_OUTPUT.put_line('Item Type in Order: ' || message4);
        END IF;
     
    END;
    /

    Consulte RECEIVE_MESSAGE Função para obter mais informações.

Remover um Pipe Persistente

Descreve as etapas para remover um pipe persistente.

Os pipes persistentes enviam e recebem mensagens armazenando mensagens no Cloud Object Store. Use DBMS_PIPE.REMOVE_PIPE para remover um pipe persistente em uma instância do Autonomous Database.

  1. Chame a função DBMS_PIPE.REMOVE_PIPE para remover um pipe.
    DECLARE
       l_result  INTEGER;
    BEGIN
         l_result := DBMS_PIPE.REMOVE_PIPE('ORDER_PIPE');
    END;
    /

    A função REMOVE_PIPE remove o pipe da instância do Autonomous Database em que ele é executado; no entanto, REMOVE_PIPE não afeta outras instâncias do Autonomous Database com um pipe com o mesmo nome que usa o mesmo URI de local.

  2. Na instância do Autonomous Database em que você executou DBMS_PIPE.REMOVE_PIPE, verifique se o pipe foi removido.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    No rows selected