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. Its interesting to play with the order of events and see how it affects the sending and receiving of messages.
-- Heres 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 isnt 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 theres a session out there that knows what to -- do with the message we sent we can be pretty sure -- its 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('Theres 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; /
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 queuesuser 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 |