Mettre en cache des messages à l'aide de canaux singletons

Singleton Pipe est un ajout à l'ensemble DBMS_PIPE qui vous permet de mettre en mémoire cache et d'extraire un message personnalisé et de partager le message entre plusieurs sessions de base de données avec des lectures simultanées.

À propos de la mise en cache de messages à l'aide de canaux singletons

L'ensemble DBMS_PIPE a une fonctionnalité étendue sur Autonomous Database pour prendre en charge les pipelines Singleton.

Un Singleton Pipe dans DBMS_PIPE :

  • Fournit la mise en mémoire cache en mémoire des données personnalisées à l'aide de messages Singleton Pipe.

  • Prend en charge la mise en mémoire cache et l'extraction d'un message personnalisé allant jusqu'à 32 767 octets.

  • Prend en charge le partage d'un message mis en cache entre plusieurs sessions de base de données avec des lectures simultanées. Cela permet un débit élevé et prend en charge les lectures simultanées de messages entre les sessions de base de données.

  • Prend en charge les bases de données en lecture seule et en lecture-écriture.

  • Prend en charge plusieurs méthodes d'invalidation du cache :

    • Invalidation explicite du cache contrôlée par l'utilisateur.
    • Invalidation du cache après l'intervalle de temps spécifié par l'utilisateur (en secondes). Cette méthode d'invalidation est contrôlée par l'expéditeur du message, à l'aide du paramètre shelflife, plutôt que par les lecteurs de message. Cela évite les pièges courants dus à une utilisation incorrecte du cache par les lecteurs.

À propos des tuyaux standard et des tuyaux singleton

L'ensemble DBMS_PIPE permet à deux sessions de base de données ou plus de communiquer à l'aide de messages en mémoire. La fonctionnalité de canal comporte plusieurs applications telles que l'interface de service externe, le débogage, les transactions indépendantes et les alertes. Pour plus d'informations, voir DBMS_PIPE dans Informations de référence sur les ensembles et les types PL/SQL pour Oracle Database 19c ou Informations de référence sur les ensembles et les types PL/SQL pour Oracle Database 23ai.

Description de database-pipe-messages-singleton-pipes.eps
Description de l'illustration database-pipe-messages-singleton-pipes.eps

Un canal Singleton peut être l'un des types DBMS_PIPE pris en charge :

  • Conduit implicite : Créé automatiquement lorsqu'un message est envoyé avec un nom de canal inconnu à l'aide de la fonction DBMS_PIPE.SEND_MESSAGE.
  • Converbe explicite : Créé à l'aide de la fonction DBMS_PIPE.CREATE_PIPE avec un nom de canal spécifié par l'utilisateur.
  • Conseil public : Accessible par tout utilisateur disposant de l'autorisation EXECUTE sur l'ensemble DBMS_PIPE.
  • Converbe privé : Accessible par les sessions avec le même utilisateur que le créateur du canal.

Les pipelines Singleton permettent de mettre en mémoire cache un seul message dans la mémoire de l'instance Autonomous Database.

Ce qui suit présente le flux de travail général pour l'utilisation de canalisations singleton.

Description de singleton-pipe-workflow.eps
Description de l'illustration singleton-pipe-workflow.eps

Aperçu et caractéristiques de Singleton Pipe

  • Messages singleton

    • Un canal Singleton peut mettre en cache un message dans le canal, d'où le nom "singleton".
    • Le message dans un Singleton Pipe peut être composé de plusieurs champs, jusqu'à une taille totale de message de 32 767 octets.
    • DBMS_PIPE prend en charge la possibilité d'emballer plusieurs attributs dans un message à l'aide de la procédure DBMS_PIPE.PACK_MESSAGE.
    • Pour un canal monocoque public, le message peut être reçu par n'importe quelle session de base de données avec le privilège d'exécution sur l'ensemble DBMS_PIPE.
    • Pour Private Singleton Pipe, le message peut être reçu par des sessions avec le même utilisateur que le créateur du Singleton Pipe.
  • Débit de messages élevé pour les lectures
    • Singleton Pipes met le message en mémoire cache dans le tuyau jusqu'à ce qu'il soit invalidé ou épuré. Les sessions de base de données peuvent lire simultanément un message à partir du canal Singleton.
    • Recevoir un message à partir d'un Singleton Pipe est une opération non bloquante.
  • Mise en mémoire cache des messages
    • Un message est mis en mémoire cache dans un canal Singleton à l'aide de DBMS_PIPE.SEND_MESSAGE.
    • S'il existe un message en mémoire cache dans le canal Singleton, DBMS_PIPE.SEND_MESSAGE remplace le message précédent pour ne conserver qu'un seul message dans le canal Singleton.
  • Invalidation du message
    • Invalidation explicite : épure le canal avec la procédure DBMS_PIPE.PURGE ou en écrasant le message à l'aide de DBMS_PIPE.SEND_MESSAGE.
    • invalidation automatique : Un message peut être invalidé automatiquement une fois le temps shelflife spécifié écoulé.
  • Aucune éviction de la mémoire de base de données
    • Les pipelines Singleton ne sont pas expulsés de la mémoire d'Oracle Database.
    • Un canal Singleton explicite continue de résider dans la mémoire de la base de données jusqu'à ce qu'il soit supprimé à l'aide de DBMS_PIPE.REMOVE_PIPE ou jusqu'au redémarrage de la base de données.
    • Un canal singleton implicite reste en mémoire de base de données jusqu'à ce qu'il y ait un message mis en cache dans le canal.

Actualisation automatique du message mis en cache avec une fonction de mémoire cache

L'ensemble DBMS_PIPE vous permet d'alimenter automatiquement un message Singleton Pipe à l'aide d'une fonction de mémoire cache définie par l'utilisateur.

Par défaut, une fois qu'un message est invalidé avec l'invalidation explicite ou implicite de Singleton Pipe, une DBMS_PIPE.RECEIVE_MESSAGE suivante entraîne la réception d'aucun message. Pour ajouter un nouveau message à la barre verticale, le message doit être explicitement mis en mémoire cache en appelant DBMS_PIPE.SEND_MESSAGE. Pour éviter ce cas, où aucun message n'est disponible lorsque vous lisez à partir d'un canal Singleton, vous pouvez définir une fonction de cache. Avec une fonction de cache définie, la fonction de cache est automatiquement appelée lorsque vous recevez un message dans les scénarios suivants :

  • Lorsque le Singleton Pipe est vide.
  • Lorsque le message dans un canal Singleton n'est pas valide en raison du temps écoulé pour shelflife.

Pour utiliser une fonction de mémoire cache, définissez la fonction de mémoire cache et incluez le paramètre cache_func avec DBMS_PIPE.RECEIVE_MESSAGE. Une fonction de cache définie par l'utilisateur fournit les éléments suivants :

  • La fonction de mémoire cache peut être spécifiée lors de la lecture d'un message à partir d'un canal Singleton à l'aide de DBMS_PIPE.RECEIVE_MESSAGE.
  • Lorsqu'il n'y a aucun message dans le canal Singleton, DBMS_PIPE.RECEIVE_MESSAGE appelle la fonction de mémoire cache.
  • Lorsque le temps du message shelflife est écoulé, la base de données alimente automatiquement un nouveau message dans le canal Singleton.

L'utilisation d'une fonction de cache simplifie l'utilisation de Singleton Pipes. Vous n'avez pas besoin de traiter les cas d'échec pour recevoir un message à partir d'un tuyau vide. En outre, une fonction de mise en cache garantit qu'il n'y a pas d'échec en mémoire cache lorsque vous lisez des messages à partir d'un canal Singleton, ce qui permet une utilisation maximale du message mis en mémoire cache.

Une description de automatic-cache-refresh-cache-function.eps suit
Description de l'illustration automatic-cache-refresh-cache-function.eps

Lorsque vous définissez une fonction de cache, le nom de la fonction doit être entièrement qualifié avec le schéma propriétaire :

  • OWNER.FUNCTION_NAME
  • OWNER.PACKAGE.FUNCTION_NAME

Définissez une fonction de cache avec la signature suivante :

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

Les opérations typiques d'une fonction de cache sont les suivantes :

  • Créez un canal Singleton, pour un canal explicite, à l'aide de DBMS_PIPE.CREATE_PIPE.
  • Créez un message à mettre en cache dans le canal Singleton.
  • Envoyez le message au canal spécifié dans la fonction de mémoire cache, en spécifiant éventuellement une valeur shelflife pour le message implicite.

Pour utiliser une fonction de mémoire cache, l'utilisateur de session courant qui appelle DBMS_PIPE.RECEIVE_MESSAGE doit disposer des privilèges requis pour exécuter la fonction de mémoire cache.

Voir RECIEVE_MESSAGE Fonction pour plus d'informations sur la définition d'une fonction de mémoire cache.

Créer un canal singleton explicite

Décrit les étapes de création d'un canal Singleton avec un nom de canal spécifié (un canal Singleton explicite).

Tout d'abord, dans cet exemple, créez la fonction d'aide receive_message pour appeler DBMS_PIPE.RECEIVE_MESSAGE de manière répétée. Cela vous permet de tester la fonctionnalité de canalisation 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. Créez un canal singleton explicite nommé PIPE_TEST avec le paramètre shelflife réglé à 3600 (secondes).
    DECLARE
      l_status INTEGER;
    BEGIN
      l_status := DBMS_PIPE.CREATE_PIPE(
                    pipename => 'MY_PIPE1',
                    private => TRUE,
                    singleton => TRUE,
                    shelflife => 3600);
    END;
    /

    Pour plus d'informations, voir CREATE_PIPE Fonction.

  2. Vérifiez que la canalisation singleton est créée.
    SELECT name, singleton, type
         FROM v$db_pipes WHERE name= '&pipename' ORDER BY 1;
    
    NAME                 SINGLETON  TYPE
    -------------------- ---------- -------
    PIPE_TEST            YES        PRIVATE
  3. Emballez et envoyez un message sur la pipe 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
  4. Recevez un message d'un singleton pipe.
    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 fonction receive_message est une fonction d'aide qui appelle DBMS_PIPE.RECEIVE_MESSAGE.

  5. Épurez le message et supprimez la barre verticale.
    EXEC DBMS_PIPE.PURGE('&pipename');
    SELECT DBMS_PIPE.REMOVE_PIPE('&pipename') status FROM DUAL;

Créer un canal singleton explicite avec une fonction Cache

Décrit les étapes de création d'un canal singleton avec un nom de canal spécifié, un canal singleton explicite, et fournit une fonction de mise en cache. Une fonction de cache vous permet d'alimenter automatiquement le message dans un canal singleton.

  1. Créez une fonction de mémoire cache, test_cache_message, pour un canal 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;
    /

    Note :

    L'utilisateur de la session courante qui appelle DBMS_PIPE.RECEIVE_MESSAGE doit disposer des privilèges requis pour exécuter la fonction de mémoire cache.
  2. Recevez avec une fonction de mémoire cache et vérifiez que le message est alimenté dans la barre verticale. Le canal doit exister en tant que canal privé créé dans la fonction de mémoire cache.
    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 fonction receive_message est une fonction d'aide qui appelle DBMS_PIPE.RECEIVE_MESSAGE. Voir Créer un canal Singleton explicite pour la définition receive_message.

    Pour plus d'informations, voir CREATE_PIPE Fonction.

  3. Recevoir sans la fonction de mémoire cache pour confirmer que le message persiste dans le canal.
    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 fonction receive_message est une fonction d'aide qui appelle DBMS_PIPE.RECEIVE_MESSAGE. Voir Créer un canal Singleton explicite pour la définition receive_message.

    Pour plus d'informations, voir CREATE_PIPE Fonction.