Usa messaggistica persistente con messaggi memorizzati nell'area di memorizzazione degli oggetti cloud

Il package DBMS_PIPE dispone di funzionalità estese su Autonomous Database per supportare la messaggistica persistente, in cui i messaggi vengono memorizzati nell'area di memorizzazione degli oggetti cloud.

Informazioni sulla messaggistica persistente con DBMS_PIPE

La messaggistica persistente con DBMS_PIPE consente a una o più sessioni di database di comunicare nella stessa area o tra più aree con i messaggi memorizzati nell'area di memorizzazione degli oggetti cloud.

Messaggi persistenti in DBMS_PIPE:

  • Permetti di inviare e recuperare messaggi molto grandi.

  • Supporta l'invio di un numero elevato di messaggi pipe.

  • Supporta l'invio e la ricezione di messaggi all'interno di un unico database, su più database e tra database in aree diverse.

  • Supporta più pipe utilizzando lo stesso URI di posizione dell'area di memorizzazione degli oggetti cloud.

È possibile creare tubi di messaggistica persistenti in uno qualsiasi dei tipi DBMS_PIPE supportati:

  • Pipe implicita: viene creato automaticamente quando viene inviato un messaggio con un nome pipe sconosciuto utilizzando la funzione DBMS_PIPE.SEND_MESSAGE.
  • Pipe esplicita: viene creato utilizzando la funzione DBMS_PIPE.CREATE_PIPE con un nome pipe specificato dall'utente.
  • Public Pipe: accessibile da qualsiasi utente con autorizzazione EXECUTE sul pacchetto DBMS_PIPE.
  • Pipe privata: è accessibile dalle sessioni con lo stesso utente dell'autore della pipe.
Nota

Oracle consiglia di creare una pipe esplicita prima di inviare o ricevere messaggi con messaggi persistenti. La creazione di una pipe esplicita con DBMS_PIPE.CREATE_PIPE garantisce che la pipe venga creata con le autorizzazioni di accesso desiderate, sia pubbliche che private (impostando il parametro private).

Di seguito è riportato il workflow generale per DBMS_PIPE con messaggi persistenti.

Descrizione di database-pipe-persistent-messaging.eps:
Descrizione dell'immagine database-pipe-persistent-messaging.eps

Le applicazioni esistenti che utilizzano DBMS_PIPE possono continuare a funzionare con modifiche minime. È possibile configurare le applicazioni esistenti che utilizzano DBMS_PIPE con un oggetto credenziali e un URI di posizione utilizzando un trigger di accesso o un'altra routine di inizializzazione. Dopo aver impostato la credenziale DBMS_PIPE e l'URI di posizione, non sono necessarie altre modifiche per utilizzare la messaggistica persistente. Tutti gli usi successivi della pipe memorizzano i messaggi nell'area di memorizzazione degli oggetti cloud anziché nella memoria del database. Ciò ti consente di modificare il metodo di storage per i messaggi da in-memory a storage degli oggetti cloud persistente, con modifiche minime.

Panoramica e funzioni di messaggistica persistente

Funzioni di DBMS_PIPE che utilizzano la messaggistica persistente:

  • I messaggi possono essere inviati e recuperati in più istanze di Autonomous Database nella stessa area o tra più aree.

  • I messaggi persistenti sono garantiti per essere scritti o letti da un solo processo. Ciò impedisce l'incongruenza del contenuto del messaggio a causa di scritture e letture concorrenti. Utilizzando una pipe di messaggistica persistente, DBMS_PIPE consente di attivare una sola operazione, l'invio di un messaggio o di un messaggio ricevente alla volta. Tuttavia, se un'operazione non è possibile a causa di un'operazione in corso, il processo ripete periodicamente fino al raggiungimento del valore timeout.

  • DBMS_PIPE utilizza DBMS_CLOUD per accedere all'area di memorizzazione degli oggetti cloud. I messaggi possono essere memorizzati in qualsiasi area di memorizzazione degli oggetti cloud supportata. Vedere DBMS_CLOUD Formati URI per ulteriori informazioni.

  • DBMS_PIPE utilizza DBMS_CLOUD per accedere all'area di memorizzazione degli oggetti cloud e sono disponibili tutti i tipi di credenziali supportati:

Autorizzazione e sicurezza dei privilegi DBMS_PIPE

Le procedure DBMS_PIPE vengono eseguite con i diritti del chiamante. I tubi privati sono di proprietà dell'utente corrente e una pipe privata creata da un utente può essere utilizzata solo dallo stesso utente. Ciò si applica sia ai tubi in memoria che ai tubi di messaggistica persistenti in cui i messaggi vengono memorizzati nell'area di memorizzazione degli oggetti cloud. L'invio e la ricezione dei messaggi vengono eseguiti nello schema del chiamante.

Utilizzando pipe private, in cui i messaggi vengono memorizzati nell'area di memorizzazione degli oggetti cloud, è necessario un oggetto credenziali per l'autenticazione con l'area di memorizzazione degli oggetti cloud identificata dal parametro location_uri. L'utente che richiama deve disporre del privilegio EXECUTE sull'oggetto credenziale specificato con il parametro credential_name utilizzato per accedere all'area di memorizzazione degli oggetti.

Per utilizzare una pipe pubblica, l'utente, la sessione del database, deve disporre del privilegio di esecuzione su DBMS_PIPE. Per una pipe pubblica che utilizza la messaggistica persistente e memorizza i messaggi nell'area di memorizzazione degli oggetti cloud, l'utente, la sessione del database, deve disporre del privilegio di esecuzione su DBMS_CLOUD ed eseguire il privilegio sull'oggetto credenziali (oppure è possibile creare un oggetto credenziali che sia autorizzato ad accedere all'URI della posizione che contiene il messaggio).

DBMS_PIPE Limitazione

Il pacchetto DBMS_PIPE non supporta l'invio di messaggi tra database che utilizzano set di caratteri diversi. Ad esempio, se si dispone di un'istanza di Autonomous Database che utilizza AL32UTF8 e un'altra istanza che utilizza WE8MSWIN1252, non è possibile inviare messaggi con DBMS_PIPE tra questi due database. In questo caso, il sistema genererà l'errore ORA-12704 se si tenta di inviare messaggi con DBMS_PIPE tra questi due database.

Per ulteriori informazioni, vedere Scegliere un set di caratteri per Autonomous Database.

Creare una pipe persistente esplicita e inviare un messaggio

Descrive i passi per creare una pipe persistente con un nome pipe specificato (Tubo esplicito).

  1. Memorizzare le credenziali dell'area di memorizzazione degli oggetti utilizzando la procedura DBMS_CLOUD.CREATE_CREDENTIAL. Ad esempio:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'my_persistent_pipe_cred',
        username => 'adb_user@example.com',
        password => 'password'
      );
    END;
    /

    Questa operazione memorizza le credenziali nel database in formato cifrato. È possibile utilizzare qualsiasi nome per il nome della credenziale. Tenere presente che questo passo è necessario una sola volta a meno che le credenziali dell'area di memorizzazione degli oggetti non vengano modificate. Dopo aver memorizzato le credenziali, è possibile utilizzare lo stesso nome di credenziale per accedere all'area di memorizzazione degli oggetti cloud per inviare e ricevere messaggi con DBMS_PIPE.

    Per informazioni dettagliate sui parametri, vedere CREATE_CREDENTIAL Procedura. Per Oracle Cloud Infrastructure Object Storage, è necessario che la credenziale utilizzi l'autenticazione nativa di Oracle Cloud Infrastructure.

    La creazione di una credenziale per accedere all'area di memorizzazione degli oggetti di Oracle Cloud Infrastructure non è necessaria se si abilitano le credenziali del principal risorsa. Per ulteriori informazioni, consulta la sezione relativa all'uso del principal delle risorse per accedere alle risorse di Oracle Cloud Infrastructure.

    Nota

    Alcuni strumenti come SQL*Plus e SQL Developer utilizzano il carattere E commerciale (&) come carattere speciale. Se la password contiene il carattere E commerciale, utilizzare il comando SET DEFINE OFF in tali strumenti, come illustrato nell'esempio per disabilitare il carattere speciale e creare correttamente la credenziale.
  2. Creare una pipe esplicita per inviare e recuperare i messaggi. Ad esempio, creare una pipe denominata ORDER_PIPE.
    DECLARE
      r_status INTEGER;
    BEGIN
        r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE');
    END;
    /

    Per ulteriori informazioni, vedere CREATE_PIPE Function.

  3. Verificare che la pipe sia stata creata.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 
  4. Utilizzare le procedure DBMS_PIPE per impostare la credenziale di accesso e l'URI di posizione predefiniti per memorizzare i messaggi persistenti nell'area di memorizzazione degli oggetti cloud.
    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;
    /

    Queste procedure impostano il nome predefinito delle credenziali e l'URI di posizione predefinito da utilizzare con le procedure DBMS_PIPE.

    Se utilizzi Oracle Cloud Infrastructure Object Storage per memorizzare i messaggi, puoi utilizzare gli URI nativi Oracle Cloud Infrastructure o gli URI Swift. Tuttavia, l'URI di posizione e la credenziale devono corrispondere nel tipo indicato di seguito.

    • Se si utilizza un formato URI nativo per accedere a Oracle Cloud Infrastructure Object Storage, è necessario utilizzare l'autenticazione delle chiavi di firma Oracle Cloud Infrastructure native nell'oggetto credenziali.

    • Se si utilizza il formato URI Swift per accedere a Oracle Cloud Infrastructure Object Storage, è necessario utilizzare un'autenticazione del token di autenticazione nell'oggetto credenziali.

    Per ulteriori informazioni, vedere SET_CREDENTIAL_NAME Procedura e Procedura SET_LOCATION_URI.

  5. Imballare e inviare un messaggio sulla 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;
    /

    Per ulteriori informazioni, vedere PACK_MESSAGE Procedure e Funzione SEND_MESSAGE.

Recupera un messaggio persistente nello stesso database

Descrive i passi per recuperare un messaggio persistente da una pipe esplicita sulla stessa istanza di Autonomous Database (l'istanza in cui è stato inviato il messaggio).

In un'istanza di Autonomous Database è possibile ricevere messaggi inviati a una pipe da una sessione diversa. Le procedure DBMS_PIPE sono procedure relative ai diritti del chiamante ed vengono eseguite come utente corrente richiamato.

I tubi privati sono di proprietà dell'utente corrente che crea il tubo. I tubi privati sono accessibili solo dallo stesso utente che ha creato il tubo. Ciò si applica alle pipe che utilizzano messaggi in memoria e alle pipe che utilizzano la messaggistica persistente con messaggi memorizzati nell'area di memorizzazione degli oggetti cloud.

È possibile accedere ai pipe pubblici da qualsiasi sessione di database con privilegio di esecuzione su DBMS_PIPE. Ciò si applica alle pipe che utilizzano messaggi in memoria e alle pipe che utilizzano la messaggistica persistente con messaggi memorizzati nell'area di memorizzazione degli oggetti cloud.

  1. Verificare che la pipe sia stata creata.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 

    Quando ci si trova nella stessa istanza di Autonomous Database e la pipe esiste, non è necessario eseguire DBMS_PIPE.CREATE_PIPE prima di ricevere un messaggio. Ciò si applica quando la pipe è stata creata sulla stessa istanza, come illustrato in Creare una pipe persistente esplicita e inviare un messaggio.

  2. Ricevere un messaggio dalla 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 ci si trova nella stessa istanza di Autonomous Database, la credenziale esiste già e non è necessario eseguire DBMS_CLOUD.CREATE_CREDENTIAL per ricevere un messaggio. Ciò si applica quando la pipe è stata creata sulla stessa istanza, come illustrato in Creare una pipe persistente esplicita e inviare un messaggio.

Per ulteriori informazioni, vedere SET_CREDENTIAL_NAME Procedura e Procedura SET_LOCATION_URI.

Per ulteriori informazioni, vedere RECEIVE_MESSAGE Function.

Recuperare un messaggio persistente creando una pipe in un database diverso

Descrive i passi per recuperare un messaggio persistente memorizzato nell'area di memorizzazione degli oggetti cloud con una pipe esplicita su un'istanza di Autonomous Database diversa dall'istanza che ha inviato il messaggio.

  1. Memorizzare le credenziali dell'area di memorizzazione degli oggetti utilizzando la procedura DBMS_CLOUD.CREATE_CREDENTIAL. Ad esempio:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'my_persistent_pipe_cred',
        username => 'adb_user@example.com',
        password => 'password'
      );
    END;
    /

    Questa operazione memorizza le credenziali nel database in formato cifrato. È possibile utilizzare qualsiasi nome per il nome della credenziale. Tenere presente che questo passo è necessario una sola volta a meno che le credenziali dell'area di memorizzazione degli oggetti non vengano modificate. Dopo aver memorizzato le credenziali, è possibile utilizzare lo stesso nome di credenziale per accedere all'area di memorizzazione degli oggetti cloud per inviare e ricevere messaggi con DBMS_PIPE.

    Per informazioni dettagliate sui parametri, vedere CREATE_CREDENTIAL Procedura.

    La creazione di una credenziale per accedere all'area di memorizzazione degli oggetti di Oracle Cloud Infrastructure non è necessaria se si abilitano le credenziali del principal risorsa. Per ulteriori informazioni, consulta la sezione relativa all'uso del principal delle risorse per accedere alle risorse di Oracle Cloud Infrastructure.

    Nota

    Alcuni strumenti come SQL*Plus e SQL Developer utilizzano il carattere E commerciale (&) come carattere speciale. Se la password contiene il carattere E commerciale, utilizzare il comando SET DEFINE OFF in tali strumenti, come illustrato nell'esempio per disabilitare il carattere speciale e creare correttamente la credenziale.
  2. Creare una pipe esplicita con lo stesso nome della pipe che ha inviato il messaggio. Ad esempio, creare una pipe denominata ORDER_PIPE.
    DECLARE
      r_status INTEGER;
    BEGIN
        r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE');
    END;
    /
  3. Verificare che la pipe sia stata creata.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 
  4. Utilizzare le procedure DBMS_PIPE per impostare le credenziali di accesso e l'URI di posizione predefiniti per l'area di memorizzazione degli oggetti in modo che DBMS_PIPE possa accedere al messaggio 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;
    /

    Queste procedure impostano il nome predefinito delle credenziali e l'URI di posizione predefinito da utilizzare con le procedure DBMS_PIPE.

    Se utilizzi Oracle Cloud Infrastructure Object Storage per memorizzare i messaggi, puoi utilizzare gli URI nativi Oracle Cloud Infrastructure o gli URI Swift. Tuttavia, l'URI di posizione e la credenziale devono corrispondere nel tipo indicato di seguito.

    • Se si utilizza un formato URI nativo per accedere a Oracle Cloud Infrastructure Object Storage, è necessario utilizzare l'autenticazione delle chiavi di firma Oracle Cloud Infrastructure native nell'oggetto credenziali.

    • Se si utilizza il formato URI Swift per accedere a Oracle Cloud Infrastructure Object Storage, è necessario utilizzare un'autenticazione del token di autenticazione nell'oggetto credenziali.

    Per ulteriori informazioni, vedere SET_CREDENTIAL_NAME Procedura e Procedura SET_LOCATION_URI.

  5. Ricevere un messaggio dalla 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;
    /

    Per ulteriori informazioni, vedere RECEIVE_MESSAGE Function.

Rimuovere una pipe persistente

Descrive i passi per rimuovere una pipe persistente.

Le pipe persistenti inviano e ricevono messaggi memorizzando i messaggi nell'area di memorizzazione degli oggetti cloud. Utilizzare DBMS_PIPE.REMOVE_PIPE per rimuovere una pipe persistente su un'istanza di Autonomous Database.

  1. Per rimuovere una pipe, richiamare la funzione DBMS_PIPE.REMOVE_PIPE.
    DECLARE
       l_result  INTEGER;
    BEGIN
         l_result := DBMS_PIPE.REMOVE_PIPE('ORDER_PIPE');
    END;
    /

    La funzione REMOVE_PIPE rimuove la pipe dall'istanza di Autonomous Database in cui viene eseguita, ma REMOVE_PIPE non influisce su altre istanze di Autonomous Database con una pipe con lo stesso nome che utilizza lo stesso URI di posizione.

  2. Nell'istanza di Autonomous Database in cui si esegue DBMS_PIPE.REMOVE_PIPE, verificare che la pipe sia stata rimossa.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    No rows selected