Mise en cache des messages avec des canaux uniques

Le canal unique est un ajout au package DBMS_PIPE qui vous permet de mettre en 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.

A propos de la mise en cache des messages avec des canaux uniques

Le package DBMS_PIPE dispose de fonctionnalités étendues sur Autonomous Database pour la prise en charge des canaux uniques.

Un pipe singleton dans DBMS_PIPE :

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

  • Prend en charge la possibilité de mettre en cache et d'extraire un message personnalisé jusqu'à 32 767 octets.

  • Prend en charge le partage d'un message en mémoire cache entre plusieurs sessions de base de données avec des lectures simultanées. Cela fournit un débit élevé et prend en charge les lectures simultanées de messages dans 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 un intervalle de temps spécifié par l'utilisateur (en secondes). Cette méthode d'invalidation est contrôlée par l'émetteur du message, à l'aide du paramètre shelflife, et non par les lecteurs de message. Cela évite les pièges courants dus à une utilisation incorrecte du cache par les lecteurs.

A propos des tuyaux standard et des tuyaux simples

Le package DBMS_PIPE permet à au moins deux sessions de base de données de communiquer à l'aide de messages en mémoire. La fonctionnalité Pipe comprend plusieurs applications telles que l'interface de service externe, le débogage, les transactions indépendantes et les alertes. Pour plus d'informations, reportez-vous à DBMS_PIPE dans Référence des types et des packages PL/SQL Oracle Database 19c ou Référence des types et des packages PL/SQL Oracle Database 23ai.

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

Un canal singleton peut être de n'importe quel type DBMS_PIPE pris en charge :

  • Tuyau implicite : créé automatiquement lorsqu'un message est envoyé avec un nom de pipeline inconnu à l'aide de la fonction DBMS_PIPE.SEND_MESSAGE.
  • Tuyau explicite : créé à l'aide de la fonction DBMS_PIPE.CREATE_PIPE avec un nom de pipeline indiqué par l'utilisateur.
  • Tuyau public : accessible par tout utilisateur disposant du droit d'accès EXECUTE sur le package DBMS_PIPE.
  • Tuyau privé : accessible par les sessions avec le même utilisateur que le créateur de canal.

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

L'exemple suivant illustre le workflow général d'utilisation des tubes singleton.

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

Présentation et fonctionnalités du tuyau singleton

  • Messages singleton

    • Un canal singleton peut mettre en cache un message dans le canal, d'où le nom "singleton".
    • Le message d'un canal unique peut être composé de plusieurs champs, jusqu'à une taille totale de message de 32 767 octets.
    • DBMS_PIPE prend en charge la possibilité de packager plusieurs attributs dans un message à l'aide de la procédure DBMS_PIPE.PACK_MESSAGE.
    • Pour un canal singleton public, le message peut être reçu par n'importe quelle session de base de données disposant du privilège d'exécution sur le package DBMS_PIPE.
    • Pour le canal Singleton privé, le message peut être reçu par des sessions avec le même utilisateur que le créateur du canal Singleton.
  • Débit de messages élevé pour les lectures
    • Les canaux simples mettent en cache le message dans le canal jusqu'à ce qu'il soit invalidé ou purgé. Les sessions de base de données peuvent lire simultanément un message à partir du canal singleton.
    • La réception d'un message à partir d'un canal unique est une opération non bloquante.
  • Mise en 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 écrase le message précédent pour ne conserver qu'un seul message dans le canal singleton.
  • Invalidation du message
    • Invalidation explicite : purge 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 automatiquement invalidé une fois la durée shelflife indiquée écoulée.
  • Aucune expulsion de la mémoire de base de données
    • Les canaux simples ne sont pas expulsés de la mémoire Oracle Database.
    • Un canal singleton explicite reste dans la mémoire de la base de données jusqu'à ce qu'il soit enlevé à l'aide de DBMS_PIPE.REMOVE_PIPE ou jusqu'au redémarrage de la base de données.
    • Un canal unique implicite reste dans la mémoire de la base de données jusqu'à ce qu'un message soit mis en cache dans le canal.

Opérations de canal simple

Opération DBMS_PIPE Fonction ou procédure

Créer un pipe singleton explicite

Fonction CREATE_PIPE

Mettre en cache un message dans un canal singleton

PACK_MESSAGE Procedures dans le manuel Oracle Database 19c PL/SQL Packages and Types Reference ou Oracle Database 23ai PL/SQL Packages and Types Reference

Fonction SEND_MESSAGE

Lire un message en cache à partir d'un canal singleton

RECIEVE_MESSAGE Function, UNPACK_MESSAGE Procedures dans Oracle Database 19c PL/SQL Packages and Types Reference ou Oracle Database 23ai PL/SQL Packages and Types Reference

Supprimer un message dans Singleton Pipe

Procédure PURGE dans le manuel Oracle Database 19c PL/SQL Packages and Types Reference ou Oracle Database 23ai PL/SQL Packages and Types Reference

Supprimer un canal simple explicite

REMOVE_PIPE Function dans le manuel Oracle Database 19c PL/SQL Packages and Types Reference ou Oracle Database 23ai PL/SQL Packages and Types Reference

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

Le package DBMS_PIPE vous permet de remplir automatiquement un message de canal unique à l'aide d'une fonction de cache définie par l'utilisateur.

Par défaut, une fois qu'un message est invalidé avec une invalidation explicite ou implicite du canal singleton, DBMS_PIPE.RECEIVE_MESSAGE suivant n'entraîne aucune réception de message. Pour ajouter un nouveau message au pipeline, 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 appelée automatiquement lorsque vous recevez un message dans les scénarios suivants :

  • Lorsque le canal singleton est vide.
  • Lorsque le message d'un canal unique n'est pas valide en raison du temps shelflife écoulé.

Pour utiliser une fonction de cache, définissez la fonction de 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 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.
  • En l'absence de message dans le canal singleton, DBMS_PIPE.RECEIVE_MESSAGE appelle la fonction de cache.
  • Lorsque la durée du message shelflife est écoulée, la base de données renseigne automatiquement un nouveau message dans le canal singleton.

L'utilisation d'une fonction de cache simplifie l'utilisation des canaux simples. Vous n'avez pas besoin de gérer les cas d'échec pour recevoir un message à partir d'un canal vide. En outre, une fonction de cache garantit qu'il n'y a pas de cache manquant lorsque vous lisez des messages à partir d'un canal singleton, ce qui permet une utilisation maximale du message mis en cache.

Description de l'image automatic-cache-refresh-cache-function.eps
Description de l'image 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 standard au sein 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 pipeline indiqué dans la fonction de cache, en indiquant éventuellement shelflife pour le message implicite.

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

Pour plus d'informations sur la définition d'une fonction de cache, reportez-vous à Fonction RECIEVE_MESSAGE.

Créer un pipe singleton explicite

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

Dans cet exemple, créez d'abord la fonction d'aide receive_message pour appeler à plusieurs reprises DBMS_PIPE.RECEIVE_MESSAGE. 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 défini sur 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, reportez-vous à Fonction CREATE_PIPE.

  2. Vérifiez que le canal singleton est créé.
    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 le tube 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 tube 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 fonction receive_message est une fonction d'aide qui appelle DBMS_PIPE.RECEIVE_MESSAGE.

  5. Purgez le message et supprimez le canal.
    EXEC DBMS_PIPE.PURGE('&pipename');
    SELECT DBMS_PIPE.REMOVE_PIPE('&pipename') status FROM DUAL;

Création d'un canal singleton explicite avec une fonction de 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 cache. Une fonction de cache vous permet de remplir automatiquement le message dans un canal singleton.

  1. Créez une fonction de 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;
    /

    Remarques :

    L'utilisateur de session en cours qui appelle DBMS_PIPE.RECEIVE_MESSAGE doit disposer du privilège requis pour exécuter la fonction de cache.
  2. Recevez avec une fonction de cache et confirmez que le message est renseigné dans le pipe. Le canal doit exister en tant que canal privé créé dans la fonction de 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. Pour obtenir la définition receive_message, reportez-vous à Création d'un pipeline singleton explicite.

    Pour plus d'informations, reportez-vous à Fonction CREATE_PIPE.

  3. Recevez sans la fonction de cache pour confirmer que le message persiste dans le pipeline.
    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. Pour obtenir la définition receive_message, reportez-vous à Création d'un pipeline singleton explicite.

    Pour plus d'informations, reportez-vous à Fonction CREATE_PIPE.