Previous Table of Contents Next


This procedure flushes the pipe and starts aging it out of the shared pool using the LRU (least recently used) algorithm.

This example code of DBMS_PIPE is in two parts. The first sends a message and waits for a reply. The second receives the message and replies. It’s interesting to play with the order of events and see how it affects the sending and receiving of messages.


-- Here’s a demo of DBMS_PIPE. First we send a message

-- and wait for a reply on a pipe we specified in our

-- message. This is basically a handshake operation you

-- might use to establish a secure line of communication

-- between two sessions.

SET SERVEROUTPUT ON

DECLARE

    OpenPipeName        VARCHAR2(30);

    SecretPipeName         VARCHAR2(30);



    SendStatus        INTEGER;

    ReceiveStatus        INTEGER;



    ReturnedPassword    VARCHAR2(30);

    ReturnedUser        VARCHAR2(30);

    ReturnedMessage        VARCHAR2(255);

BEGIN

    -- Now we get a unique name to send as our

    -- secure pipe. In order to use a pipe you must

    -- know its name, so this isn’t likely to be used

    -- by anybody other than the intended sessions.



    SecretPipeName := DBMS_PIPE.UNIQUE_SESSION_NAME;

    -- Name the regular pipe for sending.



    OpenPipeName := 'OpenPipe’;



    -- Pack the secret pipe name into the message.



    DBMS_PIPE.PACK_MESSAGE(SecretPipeName);



    -- Send the secret pipe name out to the regular pipe.



    SendStatus := DBMS_PIPE.SEND_MESSAGE(OpenPipeName);



    IF SendStatus != 0 THEN

        DBMS_OUTPUT.PUT_LINE('Sender Could not send message!’);

    END IF;



    -- Now we just wait for a reply on the secret pipe.

    -- If there’s a session out there that knows what to

    -- do with the message we sent we can be pretty sure

    -- it’s no imposter.



    ReceiveStatus := DBMS_PIPE.RECEIVE_MESSAGE(SecretPipeName, 30);

    IF ReceiveStatus = 0 THEN



        DBMS_PIPE.UNPACK_MESSAGE(ReturnedPassword);

        DBMS_PIPE.UNPACK_MESSAGE(ReturnedUser);

        DBMS_PIPE.UNPACK_MESSAGE(ReturnedMessage);



        -- Do they know the password?



        IF ReturnedPassword = 'Dilbert’ THEN

            DBMS_OUTPUT.PUT_LINE('Sender has received the following

reply:’);

            DBMS_OUTPUT.PUT_LINE(ReturnedUser);

            DBMS_OUTPUT.PUT_LINE(ReturnedMessage);

        ELSE



        -- If not, ignore them.



            DBMS_OUTPUT.PUT_LINE('Sender received an incorrect

password.’);

        END IF;

    ELSEIF ReceiveStatus > 0 THEN



        DBMS_OUTPUT.PUT_LINE('There’s nobody out there.’);

        DBMS_PIPE.PURGE(OpenPipeName);



    END IF; 



END;

/

Now that a message is in the pipe, we need a process to receive it.


-- All this does is wait for a message on the regular pipe and then

-- sends a reply on the secret pipe specified in the message received.



SET SERVEROUTPUT ON



DECLARE



    OpenPipeName        VARCHAR2(30);

    SecretPipeName         VARCHAR2(30);



    SendStatus        INTEGER;

    ReceiveStatus        INTEGER;



BEGIN



    OpenPipeName := 'OpenPipe’;



    -- Wait for a message on this pipe for 30 seconds.



    ReceiveStatus := DBMS_PIPE.RECEIVE_MESSAGE('OpenPipe’, 30);



    IF ReceiveStatus = 1 THEN

        DBMS_OUTPUT.PUT_LINE('No message was received.’);



    ELSIF ReceiveStatus = 0 THEN



        -- Load the message into our variable.



        DBMS_PIPE.UNPACK_MESSAGE(SecretPipeName);    



        -- Create a message to send back.



        DBMS_PIPE.PACK_MESSAGE('Dilbert’);

        DBMS_PIPE.PACK_MESSAGE(user);

        DBMS_PIPE.PACK_MESSAGE('Message received -- awaiting your order’);



        -- Use the secret pipe name we received to respond.



        SendStatus := DBMS_PIPE.SEND_MESSAGE(SecretPipeName);



        IF SendStatus != 0 THEN

            DBMS_OUTPUT.PUT_LINE('Could not respond to message!’);

        END IF;

    END IF;

END;

/

Advanced Queuing

Oracle8 introduces advanced queuing, which is a more sophisticated and powerful approach to interprocess communication than DBMS_ALERT or DBMS_PIPE. Advanced queuing can be synchronous or asynchronous, and because all queuing is done in tables, all messages are protected from data loss and are fully recoverable. Messages are also object types, which allows them to contain several attributes in a single unit.

A queue is used to store messages in a queue table. There are two types of queues—user queues and exception queues. An enqueue operation is used to insert a record into a queue. A dequeue operation is used to remove a record. Records are moved to an exception queue if they expire or cannot be dequeued. Queue users are called agents. An agent is a producer or consumer of messages in queues.

A time manager process can be run in the database that allows the use of timeouts and delays in queuing and dequeuing processes.

Two packages are used for advanced queuing. DBMS_AQ is used for enqueue and dequeue processes, and DBMS_AQADM is used for administrative functions, such as creating and dropping queue tables.


Previous Table of Contents Next
Используются технологии uCoz