Persistentes Messaging mit Nachrichten verwenden, die im Cloud-Objektspeicher gespeichert sind

Das DBMS_PIPE-Package verfügt über erweiterte Funktionalität in Autonomous Database, um persistentes Messaging zu unterstützen, bei dem Nachrichten im Cloud-Objektspeicher gespeichert werden.

Persistent Messaging mit DBMS_PIPE

Durch das persistente Messaging mit DBMS_PIPE kann eine oder mehrere Datenbanksessions in derselben Region oder regionsübergreifend mit Nachrichten kommunizieren, die im Cloud-Objektspeicher gespeichert sind.

Persistente Nachrichten in DBMS_PIPE:

  • Sie können sehr große Nachrichten senden und abrufen.

  • Unterstützt das Senden einer großen Anzahl von Pipe-Nachrichten.

  • Unterstützen Sie das Senden und Empfangen von Nachrichten in einer einzigen Datenbank, über mehrere Datenbanken und über Datenbanken in verschiedenen Regionen hinweg.

  • Unterstützt mehrere Pipes mit derselben Cloud-Objektspeicherort-URI.

Persistente Messaging-Pipes können in einem der unterstützten DBMS_PIPE-Typen erstellt werden:

  • Implizite Pipe: Wird automatisch erstellt, wenn eine Nachricht mit einem unbekannten Pipe-Namen mit der Funktion DBMS_PIPE.SEND_MESSAGE gesendet wird.
  • Explizite Pipe: Wird mit der Funktion DBMS_PIPE.CREATE_PIPE mit einem benutzerdefinierten Pipe-Namen erstellt.
  • Öffentliche Pipe: Zugriff durch jeden Benutzer mit der Berechtigung EXECUTE für das Package DBMS_PIPE.
  • Private Pipe: Zugriff durch Sessions mit demselben Benutzer wie der Pipe-Ersteller.
Hinweis

Oracle empfiehlt, eine explizite Pipe zu erstellen, bevor Sie Nachrichten mit persistentem Messaging senden oder empfangen. Durch das Erstellen einer expliziten Pipe mit DBMS_PIPE.CREATE_PIPE wird sichergestellt, dass die Pipe mit den gewünschten Zugriffsberechtigungen (öffentlich oder privat) erstellt wird (indem der Parameter private festgelegt wird).

Im Folgenden wird der allgemeine Workflow für DBMS_PIPE mit persistentem Messaging dargestellt:

Beschreibung von database-pipe-persistent-messaging.eps folgt
Beschreibung der Abbildung database-pipe-persistent-messaging.eps

Vorhandene Anwendungen, die DBMS_PIPE verwenden, können mit minimalen Änderungen weiter ausgeführt werden. Sie können vorhandene Anwendungen, die DBMS_PIPE verwenden, mit einem Zugangsdatenobjekt und einer Standort-URI mit einem Anmeldetrigger oder einer anderen Initialisierungsroutine konfigurieren. Nachdem Sie die Zugangsdaten und den Speicherort-URI DBMS_PIPE festgelegt haben, sind keine weiteren Änderungen erforderlich, um persistentes Messaging zu verwenden. Bei jeder nachfolgenden Verwendung der Pipe werden die Nachrichten im Cloud-Objektspeicher statt im Datenbankspeicher gespeichert. Auf diese Weise können Sie die Speichermethode für Nachrichten mit minimalen Änderungen von "In-Memory" in "Persistenter Cloud Object Storage" ändern.

Persistent Messaging – Überblick und Features

Features von DBMS_PIPE mit persistentem Messaging:

  • Nachrichten können über mehrere Autonomous Database-Instanzen in derselben Region oder regionsübergreifend gesendet und abgerufen werden.

  • Persistente Nachrichten werden garantiert entweder von genau einem Prozess geschrieben oder gelesen. Dadurch wird eine Inkonsistenz des Nachrichteninhalts aufgrund gleichzeitiger Schreib- und Lesevorgänge verhindert. Mit einer persistenten Messaging-Pipe lässt DBMS_PIPE zu, dass nur ein Vorgang, das Senden einer Nachricht oder einer Empfangsnachricht, zu einem bestimmten Zeitpunkt aktiv ist. Wenn ein Vorgang jedoch aufgrund eines laufenden Vorgangs nicht möglich ist, wiederholt der Prozess regelmäßig, bis der Wert timeout erreicht ist.

  • DBMS_PIPE verwendet DBMS_CLOUD, um auf den Cloud-Objektspeicher zuzugreifen. Nachrichten können in einem der unterstützten Cloud-Objektspeicher gespeichert werden. Weitere Informationen finden Sie unter DBMS_CLOUD URI-Formate.

  • DBMS_PIPE verwendet DBMS_CLOUD für den Zugriff auf den Cloud-Objektspeicher, und alle unterstützten Zugangsdatentypen sind verfügbar:

DBMS_PIPE Berechtigungen Autorisierung und Sicherheit

Die DBMS_PIPE-Prozeduren werden mit den Rechten des ausführenden Benutzers ausgeführt. Private Pipes gehören dem aktuellen Benutzer, und eine private Pipe, die von einem Benutzer erstellt wird, kann nur vom selben Benutzer verwendet werden. Dies gilt sowohl für In-Memory-Pipes als auch für persistente Messaging-Pipes, in denen Nachrichten im Cloud-Objektspeicher gespeichert werden. Nachrichten senden und empfangen, die im Schema des ausführenden Benutzers ausgeführt werden

Bei Verwendung von Private Pipes, in denen Nachrichten im Cloud-Objektspeicher gespeichert werden, ist ein Zugangsdatenobjekt für die Authentifizierung mit dem Cloud-Objektspeicher erforderlich, der durch den Parameter location_uri identifiziert wird. Der aufrufende Benutzer muss die Berechtigung EXECUTE für das Zugangsdatenobjekt haben, das mit dem Parameter credential_name angegeben ist, der für den Zugriff auf den Objektspeicher verwendet wird.

Um eine öffentliche Pipe verwenden zu können, muss der Benutzer, die Datenbanksession, über Ausführungsberechtigung für DBMS_PIPE verfügen. Bei einer öffentlichen Pipe mit persistentem Messaging und dem Speichern von Nachrichten im Cloud-Objektspeicher muss der Benutzer, die Datenbanksession, über Ausführungsberechtigungen für DBMS_CLOUD und Ausführungsberechtigungen für das Zugangsdatenobjekt verfügen (oder Sie können ein Zugangsdatenobjekt erstellen, das auf die Standort-URI zugreifen darf, die diese Nachricht enthält).

DBMS_PIPE Einschränkung

Das DBMS_PIPE-Package unterstützt das Senden von Nachrichten zwischen Datenbanken, die unterschiedliche Zeichensätze verwenden. Beispiel: Wenn Sie eine Autonomous Database-Instanz verwenden, die AL32UTF8 verwendet, und eine andere Instanz, die WE8MSWIN1252 verwendet, können Sie keine Nachrichten mit DBMS_PIPE zwischen diesen beiden Datenbanken senden. In diesem Fall löst das System den Fehler ORA-12704 aus, wenn Sie versuchen, Nachrichten mit DBMS_PIPE zwischen diesen beiden Datenbanken zu senden.

Weitere Informationen finden Sie unter Zeichensatz für Autonomous Database auswählen.

Explizite persistente Pipe erstellen und eine Nachricht senden

Beschreibt die Schritte zum Erstellen einer persistenten Pipe mit einem angegebenen Pipe-Namen (Explizite Pipe).

  1. Speichern Sie die Zugangsdaten für den Objektspeicher mit der Prozedur DBMS_CLOUD.CREATE_CREDENTIAL. Beispiel:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'my_persistent_pipe_cred',
        username => 'adb_user@example.com',
        password => 'password'
      );
    END;
    /

    Dieser Vorgang speichert die Zugangsdaten in einem verschlüsselten Format in der Datenbank. Sie können einen beliebigen Namen als Zugangsdatenname verwenden. Beachten Sie, dass dieser Schritt nur einmal erforderlich ist, es sei denn, Ihre Objektspeicherzugangsdaten werden geändert. Nachdem Sie die Zugangsdaten gespeichert haben, können Sie mit demselben Zugangsdatennamen auf den Cloud-Objektspeicher zugreifen, um Nachrichten mit DBMS_PIPE zu senden und zu empfangen.

    Ausführliche Informationen zu den Parametern finden Sie unter Prozedur CREATE_CREDENTIAL. Für Oracle Cloud Infrastructure Object Storage müssen die Zugangsdaten die native Oracle Cloud Infrastructure-Authentifizierung verwenden.

    Das Erstellen von Zugangsdaten für den Zugriff auf den Oracle Cloud Infrastructure-Objektspeicher ist nicht erforderlich, wenn Sie Resource-Principal-Zugangsdaten aktivieren. Weitere Informationen finden Sie unter Resource Principal für den Zugriff auf Oracle Cloud Infrastructure-Ressourcen nutzen.

    Hinweis

    Einige Tools wie SQL*Plus und SQL Developer verwenden das Et-Zeichen (&) als Sonderzeichen. Wenn das Et-Zeichen in Ihrem Kennwort enthalten ist, verwenden Sie den Befehl SET DEFINE OFF in diesen Tools, wie im Beispiel gezeigt, um das Sonderzeichen zu deaktivieren und die Zugangsdaten ordnungsgemäß zu erstellen.
  2. Erstellen Sie eine explizite Pipe zum Senden und Abrufen von Nachrichten. Beispiel: Erstellen Sie eine Pipe namens ORDER_PIPE.
    DECLARE
      r_status INTEGER;
    BEGIN
        r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE');
    END;
    /

    Weitere Informationen finden Sie unter Funktion CREATE_PIPE.

  3. Vergewissern Sie sich, dass die Pipe erstellt wurde.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 
  4. Verwenden Sie DBMS_PIPE-Prozeduren, um die Standardzugriffszugangsdaten und die Standort-URI festzulegen, um persistente Nachrichten im Cloud-Objektspeicher zu speichern.
    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;
    /

    Diese Prozeduren legen den Standardzugangsdatennamen und die Standardverzeichnis-URI für die Verwendung mit DBMS_PIPE-Prozeduren fest.

    Wenn Sie Nachrichten in Oracle Cloud Infrastructure Object Storage speichern, können Sie native Oracle Cloud Infrastructure-URIs oder Swift-URIs verwenden. Der Speicherort-URI und die Zugangsdaten müssen jedoch wie folgt mit dem Typ übereinstimmen:

    • Wenn Sie für den Zugriff auf Oracle Cloud Infrastructure Object Storage ein natives URI-Format verwenden, müssen Sie die Authentifizierung mit nativen Oracle Cloud Infrastructure-Signaturschlüsseln im Zugangsdatenobjekt verwenden.

    • Wenn Sie das Swift-URI-Format für den Zugriff auf Oracle Cloud Infrastructure Object Storage verwenden, müssen Sie eine Authentifizierungstokenauthentifizierung im Zugangsdatenobjekt verwenden.

    Weitere Informationen finden Sie unter Prozedur SET_CREDENTIAL_NAME und Prozedur SET_LOCATION_URI.

  5. Verpacken und senden Sie eine Nachricht in der Pipe.
    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;
    /

    Weitere Informationen finden Sie unter PACK_MESSAGE Prozeduren und SEND_MESSAGE-Funktion.

Persistente Nachricht in derselben Datenbank abrufen

Beschreibt die Schritte zum Abrufen einer persistenten Nachricht aus einer expliziten Pipe auf derselben Autonomous Database-Instanz (der Instanz, an die die Nachricht gesendet wurde).

In einer Autonomous Database-Instanz können Sie Nachrichten empfangen, die aus einer anderen Session an eine Pipe gesendet werden. Die DBMS_PIPE-Prozeduren sind die Rechteprozeduren des Aufrufers und werden als aktuell aufgerufener Benutzer ausgeführt.

Private Pipes gehören dem aktuellen Benutzer, der die Pipe erstellt. Private Pipes können nur von demselben Benutzer aufgerufen werden, der die Pipe erstellt hat. Dies gilt für Pipes, die In-Memory-Nachrichten verwenden, und für Pipes, die persistentes Messaging mit Nachrichten verwenden, die im Cloud-Objektspeicher gespeichert sind.

Öffentliche Pipes können von jeder Datenbanksession mit Ausführungsberechtigung für DBMS_PIPE aufgerufen werden. Dies gilt für Pipes, die In-Memory-Nachrichten verwenden, und für Pipes, die persistentes Messaging mit Nachrichten verwenden, die im Cloud-Objektspeicher gespeichert sind.

  1. Vergewissern Sie sich, dass die Pipe erstellt wurde.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 

    Wenn Sie sich auf derselben Autonomous Database-Instanz befinden und die Pipe vorhanden ist, müssen Sie DBMS_PIPE.CREATE_PIPE nicht ausführen, bevor Sie eine Nachricht erhalten. Dies gilt, wenn die Pipe auf derselben Instanz erstellt wurde, wie unter Explizite persistente Pipe und Nachricht senden gezeigt.

  2. Empfangen Sie eine Nachricht von der Pipe.
    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;
    /

    Wenn Sie sich in derselben Autonomous Database-Instanz befinden, sind die Zugangsdaten bereits vorhanden, und Sie müssen DBMS_CLOUD.CREATE_CREDENTIAL nicht ausführen, um eine Meldung zu erhalten. Dies gilt, wenn die Pipe auf derselben Instanz erstellt wurde, wie unter Explizite persistente Pipe und Nachricht senden gezeigt.

Weitere Informationen finden Sie unter Prozedur SET_CREDENTIAL_NAME und Prozedur SET_LOCATION_URI.

Weitere Informationen finden Sie unter Funktion RECEIVE_MESSAGE.

Persistente Nachricht durch Erstellen einer Pipe in einer anderen Datenbank abrufen

Beschreibt die Schritte zum Abrufen einer persistenten Nachricht, die im Cloud-Objektspeicher gespeichert ist, mit einer expliziten Pipe auf einer Autonomous Database-Instanz, die sich von der Instanz unterscheidet, von der die Nachricht gesendet wurde.

  1. Speichern Sie die Zugangsdaten für den Objektspeicher mit der Prozedur DBMS_CLOUD.CREATE_CREDENTIAL. Beispiel:
    BEGIN
      DBMS_CLOUD.CREATE_CREDENTIAL(
        credential_name => 'my_persistent_pipe_cred',
        username => 'adb_user@example.com',
        password => 'password'
      );
    END;
    /

    Dieser Vorgang speichert die Zugangsdaten in einem verschlüsselten Format in der Datenbank. Sie können einen beliebigen Namen als Zugangsdatenname verwenden. Beachten Sie, dass dieser Schritt nur einmal erforderlich ist, es sei denn, Ihre Objektspeicherzugangsdaten werden geändert. Nachdem Sie die Zugangsdaten gespeichert haben, können Sie mit demselben Zugangsdatennamen auf den Cloud-Objektspeicher zugreifen, um Nachrichten mit DBMS_PIPE zu senden und zu empfangen.

    Ausführliche Informationen zu den Parametern finden Sie unter Prozedur CREATE_CREDENTIAL.

    Das Erstellen von Zugangsdaten für den Zugriff auf den Oracle Cloud Infrastructure-Objektspeicher ist nicht erforderlich, wenn Sie Resource-Principal-Zugangsdaten aktivieren. Weitere Informationen finden Sie unter Resource Principal für den Zugriff auf Oracle Cloud Infrastructure-Ressourcen nutzen.

    Hinweis

    Einige Tools wie SQL*Plus und SQL Developer verwenden das Et-Zeichen (&) als Sonderzeichen. Wenn das Et-Zeichen in Ihrem Kennwort enthalten ist, verwenden Sie den Befehl SET DEFINE OFF in diesen Tools, wie im Beispiel gezeigt, um das Sonderzeichen zu deaktivieren und die Zugangsdaten ordnungsgemäß zu erstellen.
  2. Erstellen Sie eine explizite Pipe mit demselben Namen wie die Pipe, von der die Nachricht gesendet wurde. Beispiel: Erstellen Sie eine Pipe namens ORDER_PIPE.
    DECLARE
      r_status INTEGER;
    BEGIN
        r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE');
    END;
    /
  3. Vergewissern Sie sich, dass die Pipe erstellt wurde.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    OWNERID NAME       TYPE    
    ------- ---------- ------- 
         80 ORDER_PIPE PRIVATE 
  4. Verwenden Sie DBMS_PIPE-Prozeduren, um die Standardzugriffszugangsdaten und die Standort-URI für den Objektspeicher festzulegen, damit DBMS_PIPE auf die persistente Nachricht zugreifen kann.
    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;
    /

    Diese Prozeduren legen den Standardzugangsdatennamen und die Standardverzeichnis-URI für die Verwendung mit DBMS_PIPE-Prozeduren fest.

    Wenn Sie Nachrichten in Oracle Cloud Infrastructure Object Storage speichern, können Sie native Oracle Cloud Infrastructure-URIs oder Swift-URIs verwenden. Der Speicherort-URI und die Zugangsdaten müssen jedoch wie folgt mit dem Typ übereinstimmen:

    • Wenn Sie für den Zugriff auf Oracle Cloud Infrastructure Object Storage ein natives URI-Format verwenden, müssen Sie die Authentifizierung mit nativen Oracle Cloud Infrastructure-Signaturschlüsseln im Zugangsdatenobjekt verwenden.

    • Wenn Sie das Swift-URI-Format für den Zugriff auf Oracle Cloud Infrastructure Object Storage verwenden, müssen Sie eine Authentifizierungstokenauthentifizierung im Zugangsdatenobjekt verwenden.

    Weitere Informationen finden Sie unter Prozedur SET_CREDENTIAL_NAME und Prozedur SET_LOCATION_URI.

  5. Empfangen Sie eine Nachricht von der persistenten Pipe.
    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;
    /

    Weitere Informationen finden Sie unter Funktion RECEIVE_MESSAGE.

Persistente Pipe entfernen

Beschreibt die Schritte zum Entfernen einer persistenten Pipe.

Persistente Pipes senden und empfangen Nachrichten, indem sie Nachrichten im Cloud-Objektspeicher speichern. Verwenden Sie DBMS_PIPE.REMOVE_PIPE, um eine persistente Pipe in einer Autonomous Database-Instanz zu entfernen.

  1. Rufen Sie die Funktion DBMS_PIPE.REMOVE_PIPE auf, um eine Pipe zu entfernen.
    DECLARE
       l_result  INTEGER;
    BEGIN
         l_result := DBMS_PIPE.REMOVE_PIPE('ORDER_PIPE');
    END;
    /

    Die Funktion REMOVE_PIPE entfernt die Pipe aus der Autonomous Database-Instanz, in der sie ausgeführt wird. REMOVE_PIPE wirkt sich jedoch nicht auf andere Autonomous Database-Instanzen mit einer Pipe mit demselben Namen aus, die denselben Speicherort-URI verwendet.

  2. Wenn Sie in der Autonomous Database-Instanz DBMS_PIPE.REMOVE_PIPE ausgeführt haben, prüfen Sie, ob die Pipe entfernt wurde.
    SELECT ownerid, name, type FROM v$db_pipes 
           WHERE name = 'ORDER_PIPE';
    
    No rows selected