Mensajes de Caché con Pipes Singleton

Singleton Pipe es una adición al paquete DBMS_PIPE que permite almacenar en caché y recuperar un mensaje personalizado y compartir el mensaje en varias sesiones de base de datos con lecturas simultáneas.

Acerca del Almacenamiento en Caché de Mensajes con Pipes Singleton

El paquete DBMS_PIPE tiene una funcionalidad ampliada en Autonomous Database para soportar pipes Singleton.

Un tubo Singleton en DBMS_PIPE:

  • Proporciona almacenamiento en caché en memoria de datos personalizados mediante mensajes de Singleton Pipe.

  • Admite la capacidad de almacenar en caché y recuperar un mensaje personalizado de hasta 32.767 bytes.

  • Soporta el uso compartido de un mensaje almacenado en caché en varias sesiones de base de datos con lecturas simultáneas. Esto proporciona un alto rendimiento y soporta lecturas simultáneas de mensajes en sesiones de base de datos.

  • Admite bases de datos de solo lectura y de lectura y escritura.

  • Soporta varios métodos de invalidación de la caché:

    • Invalidación explícita de caché controlada por el usuario.
    • Invalidación de caché después de un intervalo de tiempo especificado por el usuario (en segundos). Este método de invalidación lo controla el remitente del mensaje, mediante el parámetro shelflife, en lugar de los lectores de mensajes. Esto evita las trampas comunes debido al uso incorrecto de caché por parte de los lectores.

Acerca de las tuberías estándar y las tuberías Singleton

El paquete DBMS_PIPE permite que dos o más sesiones de base de datos se comuniquen mediante mensajes en memoria. La funcionalidad Pipe tiene varias aplicaciones, como interfaz de servicio externo, depuración, transacciones independientes y alertas.

Descripción de base de datos-pipe-messages-singleton-pipes.eps

Un tubo Singleton puede ser cualquiera de los tipos DBMS_PIPE admitidos:

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

Los pipes Singleton proporcionan la capacidad de almacenar en caché un solo mensaje en la memoria de la instancia de Autonomous Database.

A continuación, se muestra el flujo de trabajo general para utilizar pipas singleton.

Descripción de singleton-pipe-workflow.eps

Descripción general y características del tubo Singleton

  • Mensajes Singleton

    • Una tubería Singleton puede almacenar en caché un mensaje en la tubería, de ahí el nombre "singleton".
    • El mensaje en una tubería Singleton puede estar compuesto por varios campos, hasta un tamaño total de mensaje de 32.767 bytes.
    • DBMS_PIPE admite la capacidad de empaquetar varios atributos en un mensaje mediante el procedimiento DBMS_PIPE.PACK_MESSAGE.
    • Para un canal Singleton público, el mensaje puede ser recibido por cualquier sesión de base de datos con privilegio de ejecución en el paquete DBMS_PIPE.
    • Para Private Singleton Pipe, el mensaje puede ser recibido por sesiones con el mismo usuario que el creador de Singleton Pipe.
  • Alto rendimiento de mensajes para lecturas
    • Los pipes singleton almacenan en caché el mensaje en el conducto hasta que se invalida o se depura. Las sesiones de base de datos pueden leer simultáneamente un mensaje del canal Singleton.
    • Recibir un mensaje de una tubería Singleton es una operación sin bloqueo.
  • Almacenamiento en Caché de Mensajes
    • Un mensaje se almacena en caché en un canal Singleton mediante DBMS_PIPE.SEND_MESSAGE.
    • Si hay un mensaje en caché existente en Singleton Pipe, DBMS_PIPE.SEND_MESSAGE sobrescribe el mensaje anterior para mantener solo un mensaje en Singleton Pipe.
  • Invalidación de Mensajes
    • Invalidación explícita: depura el conducto con el procedimiento DBMS_PIPE.PURGE o sobrescribiendo el mensaje mediante DBMS_PIPE.SEND_MESSAGE.
    • Invalidación automática: un mensaje se puede invalidar automáticamente después de que haya transcurrido el tiempo shelflife especificado.
  • Sin expulsión de la memoria de base de datos
    • Los pipes Singleton no se expulsan de la memoria de Oracle Database.
    • Un conducto singleton explícito sigue residiendo en la memoria de la base de datos hasta que se elimina mediante DBMS_PIPE.REMOVE_PIPE o hasta que se reinicia la base de datos.
    • Un tubo Singleton implícito permanece en la memoria de la base de datos hasta que haya un mensaje almacenado en caché en el conducto.

Operaciones de tubería Singleton

Operación DBMS_PIPE Función o procedimiento

Creación de un conducto singleton explícito

Función CREATE_PIPE

Almacenar en caché un mensaje en pipa singleton

PACK_MESSAGE Procedures, Función SEND_MESSAGE

Leer un mensaje en caché de Singleton Pipe

Función RECEIVE_MESSAGE, Procedimientos UNPACK_MESSAGE

Borrar un mensaje en Singleton Pipe

Procedimiento de depuración

Eliminación de un conducto singleton explícito

Función REMOVE_PIPE

Refrescamiento Automático de Mensaje en Caché con una Función de Caché

El paquete DBMS_PIPE permite rellenar automáticamente un mensaje de canalización única mediante una función de caché definida por el usuario.

Por defecto, después de que un mensaje se invalida con una invalidación explícita o implícita de Singleton Pipe, un DBMS_PIPE.RECEIVE_MESSAGE posterior no da como resultado que no se reciba ningún mensaje. Para agregar un nuevo mensaje al canal, el mensaje se debe almacenar explícitamente en caché llamando a DBMS_PIPE.SEND_MESSAGE. Para evitar este caso, donde no hay ningún mensaje disponible al leer desde una tubería Singleton, puede definir una función de caché. Con una función de caché definida, la función de caché se llama automáticamente cuando recibe un mensaje en los siguientes escenarios:

  • Cuando el tubo Singleton está vacío.
  • Cuando el mensaje de un canal singleton no es válido debido al tiempo transcurrido de shelflife.

Para utilizar una función de caché, defina la función de caché e incluya el parámetro cache_func con DBMS_PIPE.RECEIVE_MESSAGE. Una función de caché definida por el usuario proporciona lo siguiente:

  • La función de caché se puede especificar al leer un mensaje desde un canal Singleton con DBMS_PIPE.RECEIVE_MESSAGE.
  • Cuando no hay ningún mensaje en el canal Singleton, DBMS_PIPE.RECEIVE_MESSAGE llama a la función de caché.
  • Cuando ha transcurrido el tiempo del mensaje shelflife, la base de datos rellena automáticamente un nuevo mensaje en el canal Singleton.

El uso de una función de caché simplifica el trabajo con pipes singleton. No es necesario gestionar los casos de fallo para recibir un mensaje de un conducto vacío. Además, una función de caché garantiza que no haya errores de caché al leer mensajes de un canal Singleton, lo que proporciona el máximo uso del mensaje almacenado en caché.

Descripción de automatic-cache-refresh-cache-function.eps

Al definir una función de caché, el nombre de la función debe estar totalmente cualificado con el esquema de propietario:

  • OWNER.FUNCTION_NAME
  • OWNER.PACKAGE.FUNCTION_NAME

Defina una función de caché con la siguiente firma:

CREATE OR REPLACE FUNCTION cache_function_name(
       pipename  IN VARCHAR2
) RETURN INTEGER;

Las operaciones típicas dentro de una función de caché son:

  • Cree un conducto singleton, para un conducto explícito, mediante DBMS_PIPE.CREATE_PIPE.
  • Cree un mensaje para almacenar en caché en Singleton Pipe.
  • Envíe el mensaje al canal especificado en la función de caché, especificando opcionalmente un shelflife para el mensaje implícito.

Para utilizar una función de caché, el usuario de sesión actual que llama a DBMS_PIPE.RECEIVE_MESSAGE debe tener los privilegios necesarios para ejecutar la función de caché.

Consulte Función RECEIVE_MESSAGE para obtener más información sobre la definición de una función de caché.

Creación de un conducto singleton explícito

Describe los pasos para crear un canal Singleton con un nombre de canal especificado (un canal Singleton explícito).

En primer lugar, para este ejemplo, cree la función de ayuda receive_message para llamar repetidamente a DBMS_PIPE.RECEIVE_MESSAGE. Esto le permite probar la funcionalidad de tubería singleton.

CREATE OR REPLACE FUNCTION msg_types AS
       TYPE t_rcv_row IS RECORD (c1 VARCHAR2(32767), c2 NUMBER);
       TYPE t_rcv_tab IS TABLE OF t_rcv_row;
END;


CREATE OR REPLACE FUNCTION receive_message(
      pipename    IN VARCHAR2,
      rcv_count   IN NUMBER DEFAULT 1,
      cache_func  IN VARCHAR2 DEFAULT NULL)
   RETURN msg_types.t_rcv_tab pipelined
    AS
       l_msg    VARCHAR2(32767);
       l_status NUMBER;
 BEGIN
      FOR i IN 1..rcv_count LOOP
           l_status := DBMS_PIPE.RECEIVE_MESSAGE(
            pipename   => pipename,
            cache_func => cache_func,
            timeout    => 1);
         IF l_status != 0 THEN
              raise_application_error(-20000,
             'Message not received for attempt: ' || to_char(i) || ' status: ' ||
            l_status);
         END IF;

         DBMS_PIPE.UNPACK_MESSAGE(l_msg);
             pipe row(msg_types.t_rcv_row(l_msg));
     END LOOP;
 RETURN;
 END;
  1. Cree un canal singleton explícito denominado PIPE_TEST con el parámetro shelflife definido en 3600 (segundos).
    DECLARE
      l_status INTEGER;
    BEGIN
      l_status := DBMS_PIPE.CREATE_PIPE(
                    pipename => 'MY_PIPE1',
                    private => TRUE,
                    singleton => TRUE,
                    shelflife => 3600);
    END;
    /

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

  2. Verifique que se haya creado el conducto singleton.
    SELECT name, singleton, type
         FROM v$db_pipes WHERE name= '&pipename' ORDER BY 1;
    
    NAME                 SINGLETON  TYPE
    -------------------- ---------- -------
    PIPE_TEST            YES        PRIVATE
  3. Empaque y envíe un mensaje en el conducto singleton.
    
    EXEC DBMS_PIPE.PACK_MESSAGE('This is a real message that you can get multiple times');
    
    SELECT DBMS_PIPE.SEND_MESSAGE(pipename => '&pipename') status FROM DUAL;
    
    STATUS
    ----------
    0

    Consulte PACK_MESSAGE Procedures y SEND_MESSAGE Function para obtener más información.

  4. Reciba un mensaje de un canal único.
    SELECT * FROM receive_message(
        pipename => '&pipename',
        rcv_count => 2);
    
    MESSAGE
    --------------------------------------------------------------------------------
    This is a real message that you can get multiple times
    This is a real message that you can get multiple times

    La función receive_message es una función auxiliar que llama a DBMS_PIPE.RECEIVE_MESSAGE.

  5. Depure el mensaje y elimine el conducto.
    EXEC DBMS_PIPE.PURGE('&pipename');
    SELECT DBMS_PIPE.REMOVE_PIPE('&pipename') status FROM DUAL;

Creación de un conducto singleton explícito con una función de caché

Describe los pasos para crear un canal Singleton con un nombre de canal especificado, un canal Singleton explícito y proporcionar una función de caché. Una función de caché permite rellenar automáticamente el mensaje en un canal único.

  1. Cree una función de caché, test_cache_message para un conducto singleton.
    CREATE OR REPLACE FUNCTION test_cache_message(
         pipename IN VARCHAR2) return NUMBER 
    AS 
       l_status NUMBER;
       l_data VARCHAR2(4000);
    BEGIN
       l_status := DBMS_PIPE.CREATE_PIPE(
              pipename => pipename,
              private => TRUE,
              singleton => true,
              shelflife => 600);
       IF l_status != 0 THEN RETURN l_status;
       END IF;
     
       DBMS_PIPE.PACK_MESSAGE('This is a placeholder cache message for an empty pipe');
       l_status := DBMS_PIPE.SEND_MESSAGE(pipename => pipename);
       RETURN l_status;
     END;
    /
    Nota

    El usuario de la sesión actual que llama a DBMS_PIPE.RECEIVE_MESSAGE debe tener el privilegio necesario para ejecutar la función de caché.
  2. Recibir con una función de caché y confirmar que el mensaje se rellena en conducción. El conducto debe existir como un conducto privado creado en la función de caché.
    SELECT * FROM receive_message(
         pipename => '&pipename',
         rcv_count => 1,
         cache_func => 'TEST_CACHE_MESSAGE');
    
    MESSAGE
    ---------------
    This is a placeholder cache message for an empty pipe
    

    La función receive_message es una función auxiliar que llama a DBMS_PIPE.RECEIVE_MESSAGE. Consulte Create an Explicit Singleton Pipe para obtener la definición receive_message.

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

  3. Recibir sin la función de caché para confirmar que el mensaje persiste en el conducto.
    SELECT * FROM receive_message(
         pipename => '&pipename',
         rcv_count => 2);
    
    MESSAGE
    ---------------
    This is a placeholder cache message for an empty pipe
    This is a placeholder cache message for an empty pipe

    La función receive_message es una función auxiliar que llama a DBMS_PIPE.RECEIVE_MESSAGE. Consulte Create an Explicit Singleton Pipe para obtener la definición receive_message.

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