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 in più aree con messaggi memorizzati nell'area di memorizzazione degli oggetti cloud.

Messaggi persistenti in DBMS_PIPE:

  • Consente di inviare e recuperare messaggi di grandi dimensioni.

  • 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.

I tubi di messaggistica persistenti possono essere creati in uno qualsiasi dei tipi DBMS_PIPE supportati:

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

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

Di seguito viene illustrato il workflow generale per DBMS_PIPE con messaggistica persistente.

Segue la descrizione dell'immagine database-pipe-persistent-messaging.eps
Descrizione dell'illustrazione 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 credenziale 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 della 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ò consente di modificare il metodo di storage per i messaggi da storage in memoria 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 su più istanze di Autonomous Database nella stessa area o tra più aree.

  • I messaggi persistenti possono essere scritti o letti da un solo processo. Ciò impedisce l'incoerenza del contenuto del messaggio a causa di scritture e letture concorrenti. Utilizzando una pipe di messaggistica persistente, DBMS_PIPE consente l'attivazione di una sola operazione, ovvero l'invio di un messaggio o di un messaggio di ricezione alla volta. Tuttavia, se un'operazione non è possibile a causa di un'operazione in corso, il processo esegue un nuovo tentativo 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. Per ulteriori informazioni, vedere DBMS_CLOUD Formati URI.

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

DBMS_PIPE Autorizzazione e sicurezza dei privilegi

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 pipe in-memory che ai pipe 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 richiedente.

Utilizzando pipe private, in cui i messaggi vengono memorizzati nell'area di memorizzazione degli oggetti cloud, è necessario un oggetto credenziale 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, 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 credenziale (oppure è possibile creare un oggetto credenziale che consenta di 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 solleverà 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 di pipe specificato (Explicit Pipe).

  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 un formato cifrato. È possibile utilizzare qualsiasi nome per il nome della credenziale. Tenere presente che questo passo è obbligatorio 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 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 Procedure. 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 Usa principal risorsa 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 si dispone del carattere e commerciale nella password, utilizzare il comando SET DEFINE OFF in tali strumenti come mostrato nell'esempio per disabilitare il carattere speciale e ottenere la credenziale creata correttamente.
  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 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 della credenziale predefinita e l'URI della posizione predefinita da utilizzare con le procedure DBMS_PIPE.

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

    • Se utilizzi un formato URI nativo per accedere a Oracle Cloud Infrastructure Object Storage, devi 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 Procedure e SET_LOCATION_URI Procedure.

  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 Procedures e SEND_MESSAGE Function.

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 di richiamo dei diritti e vengono eseguite come utente richiamato corrente.

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

È possibile accedere alle pipe pubbliche da qualsiasi sessione di database con privilegio di esecuzione su DBMS_PIPE. Ciò si applica ai pipe che utilizzano messaggi in memoria e ai pipe che utilizzano messaggi persistenti 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 sulla 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 mostrato in Crea una pipe persistente esplicita e invia 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 sulla 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 mostrato in Crea una pipe persistente esplicita e invia un messaggio.

Per ulteriori informazioni, vedere SET_CREDENTIAL_NAME Procedure e SET_LOCATION_URI Procedure.

Per ulteriori informazioni, vedere RECEIVE_MESSAGE Function.

Recuperare un messaggio persistente creando una pipe su 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 un formato cifrato. È possibile utilizzare qualsiasi nome per il nome della credenziale. Tenere presente che questo passo è obbligatorio una sola volta a meno che le credenziali dell'area di memorizzazione degli oggetti non vengano modificate. Una volta memorizzate le credenziali, è possibile utilizzare lo stesso nome 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 Procedure.

    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 Usa principal risorsa 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 si dispone del carattere e commerciale nella password, utilizzare il comando SET DEFINE OFF in tali strumenti come mostrato nell'esempio per disabilitare il carattere speciale e ottenere la credenziale creata correttamente.
  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 la credenziale di accesso predefinita e l'URI posizione 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 della credenziale predefinita e l'URI della posizione predefinita da utilizzare con le procedure DBMS_PIPE.

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

    • Se utilizzi un formato URI nativo per accedere a Oracle Cloud Infrastructure Object Storage, devi 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 Procedure e SET_LOCATION_URI Procedure.

  5. Consente di 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.

Rimuovi una pipe persistente

Descrive i passi per rimuovere una pipe persistente.

I tubi 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. Chiamare la funzione DBMS_PIPE.REMOVE_PIPE per rimuovere una 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 si eseguiva DBMS_PIPE.REMOVE_PIPE, verificare che la pipe sia rimossa.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    No rows selected