Uso de mensajes permanentes con mensajes almacenados en Cloud Object Store

El paquete DBMS_PIPE tiene una funcionalidad ampliada en Autonomous Database para soportar mensajes persistentes, donde los mensajes se almacenan en el almacén de objetos en la nube.

Acerca de la mensajería persistente con DBMS_PIPE

La mensajería persistente con DBMS_PIPE permite que una o más sesiones de base de datos se comuniquen en la misma región o entre regiones con mensajes almacenados en el almacén de objetos en la nube.

Mensajes persistentes en DBMS_PIPE:

  • Permite enviar y recuperar mensajes muy grandes.

  • Admite el envío de un gran número de mensajes de canal.

  • Admita el envío y la recepción de mensajes en una sola base de datos, en varias bases de datos y en distintas regiones.

  • Soporta varios pipes con el mismo URI de ubicación del almacén de objetos en la nube.

Se pueden crear pipas de mensajes persistentes en cualquiera de los tipos DBMS_PIPE soportados:

  • Conducto implícito: se crea automáticamente cuando se envía un mensaje con un nombre de conducto desconocido mediante la función DBMS_PIPE.SEND_MESSAGE.
  • Conducto explícito: se crea mediante la función DBMS_PIPE.CREATE_PIPE con un nombre de conducto especificado por el usuario.
  • Conducto público: accesible para cualquier usuario con permiso EXECUTE en el paquete DBMS_PIPE.
  • Conducto privado: accesible por sesiones con el mismo usuario que el creador del conducto.
Nota

Oracle recomienda crear un canal explícito antes de enviar o recibir mensajes con mensajes persistentes. La creación de un conducto explícito con DBMS_PIPE.CREATE_PIPE garantiza que el conducto se crea con los permisos de acceso que desee, ya sea público o privado (mediante la definición del parámetro private).

A continuación se muestra el flujo de trabajo general para DBMS_PIPE con mensajes persistentes:

A continuación se muestra la descripción de database-pipe-persistent-messaging.eps
Descripción de la ilustración database-pipe-persistent-messaging.eps

Las aplicaciones existentes que utilizan DBMS_PIPE pueden seguir funcionando con cambios mínimos. Puede configurar las aplicaciones existentes que utilizan DBMS_PIPE con un URI de ubicación y objeto de credencial mediante un disparador de conexión o mediante otra rutina de inicialización. Después de definir la credencial DBMS_PIPE y el URI de ubicación, no se necesitan otros cambios para utilizar mensajes persistentes. Todo el uso posterior del canal almacena los mensajes en el almacén de objetos en la nube en lugar de en la memoria de la base de datos. Esto le permite cambiar el método de almacenamiento para mensajes de almacenamiento en memoria a almacenamiento de objetos en la nube persistente, con cambios mínimos.

Visión General y Funciones de Mensajería Persistente

Funciones de DBMS_PIPE con mensajes persistentes:

  • Los mensajes se pueden enviar y recuperar en varias instancias de Autonomous Database de la misma región o de varias regiones.

  • Se garantiza que los mensajes persistentes se escriban o lean exactamente en un proceso. Esto evita la inconsistencia de contenido del mensaje debido a escrituras y lecturas simultáneas. Mediante un conducto de mensajes persistente, DBMS_PIPE solo permite que una operación, el envío de un mensaje o un mensaje de recepción estén activos en un momento determinado. Sin embargo, si una operación no es posible debido a una operación en curso, el proceso se reintenta periódicamente hasta que se alcanza el valor timeout.

  • DBMS_PIPE utiliza DBMS_CLOUD para acceder al almacén de objetos en la nube. Los mensajes se pueden almacenar en cualquiera de los almacenes de objetos en la nube soportados. Consulte DBMS_CLOUD URI Formats para obtener más información.

  • DBMS_PIPE utiliza DBMS_CLOUD para acceder al almacén de objetos en la nube y todos los tipos de credenciales soportados están disponibles:

DBMS_PIPE Autorización y seguridad de privilegios

Los procedimientos DBMS_PIPE se ejecutan con derechos del invocador. Las tuberías privadas son propiedad del usuario actual y una tubería privada creada por un usuario solo puede ser utilizada por el mismo usuario. Esto se aplica a los pipes en memoria y a los pipes de mensajería persistentes donde los mensajes se almacenan en el almacén de objetos en la nube. El envío y la recepción de mensajes se ejecutan en el esquema del invocador.

Mediante pipas privadas, donde los mensajes se almacenan en el almacén de objetos en la nube, se necesita un objeto de credencial para la autenticación con el almacén de objetos en la nube identificado por el parámetro location_uri. El usuario que llama debe tener el privilegio EXECUTE en el objeto de credencial especificado con el parámetro credential_name que se utiliza para acceder al almacén de objetos.

Para utilizar un conducto público, el usuario, la sesión de base de datos, debe tener el privilegio de ejecución en DBMS_PIPE. Para una conducción pública que utilice mensajes persistentes y almacene mensajes en el almacén de objetos en la nube, el usuario, la sesión de base de datos, debe tener el privilegio de ejecución en DBMS_CLOUD y el privilegio de ejecución en el objeto de credencial (o puede crear un objeto de credencial que tenga permiso para acceder al URI de ubicación que contiene el mensaje).

DBMS_PIPE Limitación

El paquete DBMS_PIPE no soporta el envío de mensajes entre bases de datos que utilizan diferentes juegos de caracteres. Por ejemplo, si tiene una instancia de Autonomous Database que utiliza AL32UTF8 y otra instancia que utiliza WE8MSWIN1252, no puede enviar mensajes con DBMS_PIPE entre estas dos bases de datos. En este caso, el sistema emitirá el error ORA-12704 si intenta enviar mensajes con DBMS_PIPE entre estas dos bases de datos.

Consulte Selección de juego de caracteres para Autonomous Database para obtener más información.

Creación de un conducto persistente explícito y envío de un mensaje

Describe los pasos para crear un conducto persistente con un nombre de conducto especificado (tubo explícito).

  1. Almacene las credenciales del almacén de objetos mediante el procedimiento DBMS_CLOUD.CREATE_CREDENTIAL. Por ejemplo:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'my_persistent_pipe_cred',
        username => 'adb_user@example.com',
        password => 'password'
      );
    END;
    /

    Esta operación almacena las credenciales en la base de datos en un formato cifrado. Puede utilizar cualquier nombre para el nombre de credencial. Tenga en cuenta que este paso solo es necesario una vez, a menos que cambien las credenciales del almacén de objetos. Después de almacenar las credenciales, puede utilizar el mismo nombre de credencial para acceder al almacén de objetos en la nube y enviar y recibir mensajes con DBMS_PIPE.

    Para obtener información detallada sobre los parámetros, consulte Procedimiento CREATE_CREDENTIAL. Para Oracle Cloud Infrastructure Object Storage, es necesario que la credencial utilice la autenticación nativa de Oracle Cloud Infrastructure.

    No es necesario crear una credencial para acceder al almacén de objetos de Oracle Cloud Infrastructure si activa las credenciales de la entidad de recurso. Consulte Uso de la entidad de recurso para acceder a los recursos de Oracle Cloud Infrastructure para obtener más información.

    Nota

    Algunas herramientas como SQL*Plus y SQL Developer utilizan el carácter de ampersand (&) como carácter especial. Si tiene el carácter de ampersand en la contraseña, utilice el comando SET DEFINE OFF en esas herramientas, como se muestra en el ejemplo, para desactivar el carácter especial y obtener la credencial creada correctamente.
  2. Cree una conducción explícita para enviar y recuperar mensajes. Por ejemplo, cree un conducto denominado ORDER_PIPE.
    DECLARE
      r_status INTEGER;
    BEGIN
        r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE');
    END;
    /

    Consulte Función CREATE_PIPE para obtener más información.

  3. Verifique que se haya creado la conducción.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 
  4. Utilice los procedimientos DBMS_PIPE para definir la credencial de acceso por defecto y el URI de ubicación para almacenar mensajes persistentes en el almacén de objetos en la nube.
    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;
    /

    Estos procedimientos definen el nombre de credencial por defecto y el URI de ubicación por defecto para su uso con procedimientos DBMS_PIPE.

    Si utiliza Oracle Cloud Infrastructure Object Storage para almacenar mensajes, puede utilizar los URI nativos de Oracle Cloud Infrastructure o los URI de Swift. Sin embargo, el URI de ubicación y la credencial deben coincidir en el tipo de la siguiente manera:

    • Si utiliza un formato de URI nativo para acceder a Oracle Cloud Infrastructure Object Storage, debe utilizar la autenticación de claves de firma nativas de Oracle Cloud Infrastructure en el objeto de credencial.

    • Si utiliza el formato de URI de Swift para acceder a Oracle Cloud Infrastructure Object Storage, debe utilizar una autenticación de token de autenticación en el objeto de credencial.

    Consulte Procedimiento SET_CREDENTIAL_NAME y Procedimiento SET_LOCATION_URI para obtener más información.

  5. Empaque y envíe un mensaje en la tubería.
    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 PACK_MESSAGE Procedures y SEND_MESSAGE Function para obtener más información.

Recuperar un mensaje persistente en la misma base de datos

Describe los pasos para recuperar un mensaje persistente de una conducción explícita en la misma instancia de Autonomous Database (la instancia en la que se envió el mensaje).

En una instancia de Autonomous Database, puede recibir mensajes enviados a un canal desde una sesión diferente. Los procedimientos DBMS_PIPE son procedimientos de derechos del invocador y se ejecutan como el usuario invocado actual.

Las tuberías privadas son propiedad del usuario actual que crea la tubería. Solo puede acceder a las tuberías privadas el mismo usuario que creó la tubería. Esto se aplica a los pipes que utilizan mensajes en memoria y a los pipes que utilizan mensajes persistentes con mensajes almacenados en el almacén de objetos en la nube.

Cualquier sesión de base de datos que tenga privilegio de ejecución en DBMS_PIPE puede acceder a los pipes públicos. Esto se aplica a los pipes que utilizan mensajes en memoria y a los pipes que utilizan mensajes persistentes con mensajes almacenados en el almacén de objetos en la nube.

  1. Verifique que se haya creado la conducción.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 

    Cuando se encuentra en la misma instancia de Autonomous Database y existe la conducción, no necesita ejecutar DBMS_PIPE.CREATE_PIPE antes de recibir un mensaje. Esto se aplica cuando se creó el conducto en la misma instancia, como se muestra en Creación de un conducto persistente explícito y envío de un mensaje.

  2. Reciba un mensaje del canal.
    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;
    /

    Cuando se encuentra en la misma instancia de Autonomous Database, la credencial ya existe y no necesita ejecutar DBMS_CLOUD.CREATE_CREDENTIAL para recibir un mensaje. Esto se aplica cuando se creó el conducto en la misma instancia, como se muestra en Creación de un conducto persistente explícito y envío de un mensaje.

Consulte Procedimiento SET_CREDENTIAL_NAME y Procedimiento SET_LOCATION_URI para obtener más información.

Consulte Función RECEIVE_MESSAGE para obtener más información.

Recuperación de un mensaje persistente mediante la creación de un conducto en una base de datos diferente

Describe los pasos para recuperar un mensaje persistente almacenado en el almacén de objetos en la nube con una conducción explícita en una instancia de Autonomous Database distinta de la instancia que envió el mensaje.

  1. Almacene las credenciales del almacén de objetos mediante el procedimiento DBMS_CLOUD.CREATE_CREDENTIAL. Por ejemplo:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'my_persistent_pipe_cred',
        username => 'adb_user@example.com',
        password => 'password'
      );
    END;
    /

    Esta operación almacena las credenciales en la base de datos en un formato cifrado. Puede utilizar cualquier nombre para el nombre de credencial. Tenga en cuenta que este paso solo es necesario una vez, a menos que cambien las credenciales del almacén de objetos. Una vez almacenadas las credenciales, puede utilizar el mismo nombre de credencial para acceder al almacén de objetos en la nube y enviar y recibir mensajes con DBMS_PIPE.

    Para obtener información detallada sobre los parámetros, consulte Procedimiento CREATE_CREDENTIAL.

    No es necesario crear una credencial para acceder al almacén de objetos de Oracle Cloud Infrastructure si activa las credenciales de la entidad de recurso. Consulte Uso de la entidad de recurso para acceder a los recursos de Oracle Cloud Infrastructure para obtener más información.

    Nota

    Algunas herramientas como SQL*Plus y SQL Developer utilizan el carácter de ampersand (&) como carácter especial. Si tiene el carácter de ampersand en la contraseña, utilice el comando SET DEFINE OFF en esas herramientas, como se muestra en el ejemplo, para desactivar el carácter especial y obtener la credencial creada correctamente.
  2. Cree una conducción explícita con el mismo nombre que la conducción que envió el mensaje. Por ejemplo, cree un conducto denominado ORDER_PIPE.
    DECLARE
      r_status INTEGER;
    BEGIN
        r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE');
    END;
    /
  3. Verifique que se haya creado la conducción.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 
  4. Utilice los procedimientos DBMS_PIPE para definir la credencial de acceso por defecto y el URI de ubicación para el almacén de objetos de modo que DBMS_PIPE pueda acceder al mensaje 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;
    /

    Estos procedimientos definen el nombre de credencial por defecto y el URI de ubicación por defecto para su uso con procedimientos DBMS_PIPE.

    Si utiliza Oracle Cloud Infrastructure Object Storage para almacenar mensajes, puede utilizar los URI nativos de Oracle Cloud Infrastructure o los URI de Swift. Sin embargo, el URI de ubicación y la credencial deben coincidir en el tipo de la siguiente manera:

    • Si utiliza un formato de URI nativo para acceder a Oracle Cloud Infrastructure Object Storage, debe utilizar la autenticación de claves de firma nativas de Oracle Cloud Infrastructure en el objeto de credencial.

    • Si utiliza el formato de URI de Swift para acceder a Oracle Cloud Infrastructure Object Storage, debe utilizar una autenticación de token de autenticación en el objeto de credencial.

    Consulte Procedimiento SET_CREDENTIAL_NAME y Procedimiento SET_LOCATION_URI para obtener más información.

  5. Reciba un mensaje del conducto 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 Función RECEIVE_MESSAGE para obtener más información.

Eliminación de una tubería persistente

Describe los pasos para eliminar un conducto persistente.

Los canales persistentes envían y reciben mensajes mediante el almacenamiento de mensajes en el almacén de objetos en la nube. Utilice DBMS_PIPE.REMOVE_PIPE para eliminar un conducto persistente en una instancia de Autonomous Database.

  1. Llame a la función DBMS_PIPE.REMOVE_PIPE para eliminar un conducto.
    DECLARE
       l_result  INTEGER;
    BEGIN
         l_result := DBMS_PIPE.REMOVE_PIPE('ORDER_PIPE');
    END;
    /

    La función REMOVE_PIPE elimina la conducción de la instancia de Autonomous Database en la que se ejecuta, pero REMOVE_PIPE no afecta a otras instancias de Autonomous Database con una conducción con el mismo nombre que utiliza el mismo URI de ubicación.

  2. En la instancia de Autonomous Database en la que ha ejecutado DBMS_PIPE.REMOVE_PIPE, verifique que se ha eliminado la conducción.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    No rows selected