Mensajes en caché con canalizaciones 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 entre varias sesiones de base de datos con lecturas simultáneas.

Acerca del almacenamiento en caché de mensajes con canalizaciones Singleton

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

Una tubería Singleton en DBMS_PIPE:

  • Proporciona almacenamiento en caché en memoria de datos personalizados mediante mensajes 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 entre sesiones de base de datos.

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

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

    • Invalidación de caché explícita 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 está controlado por el remitente del mensaje, mediante el parámetro shelflife, en lugar de por los lectores de mensajes. Esto evita los errores comunes debido al uso incorrecto de la caché por parte de los lectores.

Acerca de las tuberías estándar y las tuberías de 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 la interfaz de servicio externo, la depuración, las transacciones independientes y las alertas.

Descripción de database-pipe-messages-singleton-pipes.eps a continuación
Descripción de la ilustración database-pipe-messages-singleton-pipes.eps

Una tubería Singleton puede ser 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.
  • Pipa pública: accesible para cualquier usuario con permiso EXECUTE en el paquete DBMS_PIPE.
  • Pipa privada: se puede acceder mediante sesiones con el mismo usuario que el creador del pipeline.

Los pipes de Singleton permiten almacenar en caché un único mensaje en la memoria de la instancia de Autonomous Database.

A continuación, se muestra el flujo de trabajo general para el uso de tubos singleton.

A continuación, se incluye la Descripción de singleton-pipe-workflow.eps
Descripción de la ilustración singleton-pipe-workflow.eps

Descripción general y características de Singleton Pipe

  • Mensajes de Singleton

    • Un tubo Singleton puede almacenar en caché un mensaje en el conducto, de ahí el nombre "singleton".
    • El mensaje de 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 una pleca Singleton pública, cualquier sesión de base de datos que tenga privilegios de ejecución en el paquete DBMS_PIPE puede recibir el mensaje.
    • Para la tubería Singleton privada, el mensaje puede ser recibido por sesiones con el mismo usuario que el creador de la tubería Singleton.
  • Alto rendimiento de mensajes para lecturas
    • Singleton Pipes almacena 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 de Singleton Pipe.
    • La recepción de 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 una pleca Singleton con DBMS_PIPE.SEND_MESSAGE.
    • Si existe un mensaje almacenado en caché en la pleca Singleton, DBMS_PIPE.SEND_MESSAGE sobrescribe el mensaje anterior para mantener solo un mensaje en la pleca Singleton.
  • Invalidación del mensaje
    • Invalidación explícita: depura el conducto con el procedimiento DBMS_PIPE.PURGE o sobrescribiendo el mensaje con DBMS_PIPE.SEND_MESSAGE.
    • Invalidación automática: un mensaje se puede invalidar automáticamente después de que haya transcurrido el tiempo especificado de shelflife.
  • Sin expulsión de la memoria de la base de datos
    • Los pipes de Singleton no se expulsan de la memoria de Oracle Database.
    • Una pipa Singleton explícita 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 conducto 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 una tubería singleton explícita

Función CREATE_PIPE

Almacenar en caché un mensaje en Singleton Pipe

PACK_MESSAGE Procedimientos, Función SEND_MESSAGE

Leer un mensaje almacenado en caché de Singleton Pipe

RECEIVE_MESSAGE Function, UNPACK_MESSAGE Procedures

Suprimir un mensaje en Singleton Pipe

Procedimiento de PURGE

Eliminación de una tubería singleton explícita

Función REMOVE_PIPE

Actualización automática de mensajes en caché con una función de caché

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

Por defecto, una vez que un mensaje se invalida con invalidación explícita o implícita de Singleton Pipe, un DBMS_PIPE.RECEIVE_MESSAGE posterior no genera que se reciba ningún mensaje. Para agregar un nuevo mensaje al conducto, el mensaje se debe almacenar explícitamente en caché llamando a DBMS_PIPE.SEND_MESSAGE. Para evitar este caso, cuando no hay ningún mensaje disponible al leer desde un tubo 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 tubo Singleton no es válido debido al tiempo transcurrido 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 de una pleca Singleton mediante DBMS_PIPE.RECEIVE_MESSAGE.
  • Cuando no hay ningún mensaje en el conducto 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 la pleca Singleton.

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

A continuación, se incluye la Descripción de automatic-cache-refresh-cache-function.eps
Descripción de la ilustración Automated-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 tubo singleton, para un tubo explícito, mediante DBMS_PIPE.CREATE_PIPE.
  • Cree un mensaje para almacenar en caché en el tubo Singleton.
  • Envíe el mensaje al conducto especificado en la función de caché y, opcionalmente, especifique un shelflife para el mensaje implícito.

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

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

Creación de una tubería singleton explícita

Describe los pasos para crear una pleca Singleton con un nombre de pleca especificado (una pleca Singleton explícita).

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 conducto 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 CREATE_PIPE Function para obtener más información.

  2. Verifique que se haya creado la tubería singleton.
    SELECT name, singleton, type
         FROM v$db_pipes WHERE name= '&pipename' ORDER BY 1;
    
    NAME                 SINGLETON  TYPE
    -------------------- ---------- -------
    PIPE_TEST            YES        PRIVATE
  3. Empaquetar y enviar 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 una tubería singleton.
    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 una Tubería Singleton Explícita con una Función de Caché

Describe los pasos para crear una pleca Singleton con un nombre de pleca especificado, una pleca Singleton explícita y proporcionar una función de caché. Una función de caché le permite rellenar automáticamente el mensaje en un conducto singleton.

  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 el conducto. El conducto debe existir como 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 CREATE_PIPE Function 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 CREATE_PIPE Function para obtener más información.