There is only one private memory buffer per user that is used to send and receive messages on database pipes.. Private buffers can be thought of as "mailboxes" −− one for each user −− an
Trang 1REMOVE_PIPE Removes the named pipe Yes
UNIQUE_SESSION_NAME Returns string unique to the session Yes
UNPACK_MESSAGE_RAW Unpacks RAW item from message buffer No
UNPACK_MESSAGE_ROWID Unpacks ROWID item from message buffer No
DBMS_PIPE does not declare any package exceptions of its own Many of the individual programs raise Oracle exceptions under certain circumstances, as described in the following sections
3.1.1.2 DBMS_PIPE nonprogram elements
The DBMS_PIPE package contains one nonprogram element, maxwait It is defined as follows:
maxwait CONSTANT INTEGER := 86400000;
The maxwait constant is used as the default maximum time to wait for calls to the SEND_MESSAGE or RECEIVE_MESSAGE functions to complete The units are in seconds, so the value of 86400000 equates to
1000 days
3.1.2 How Database Pipes Work
It is important to understand how DBMS_PIPE implements the concept of a communications pipe between Oracle sessions −− and this implementation is not necessarily obvious
3.1.2.1 Memory structures
The pipes themselves are named memory areas in the Oracle SGA's shared pool where communications messages can be written or read DBMS_PIPE works through the interaction of these memory areas with a private memory buffer in each user's session There is only one private memory buffer per user that is used to send and receive messages on database pipes Private buffers can be thought of as "mailboxes" −− one for each user −− and the database pipes are like the "post office." The difference is that users are responsible for delivering and retrieving messages to and from the post office.[1]
[1] Dan Clamage (technical reviewer extraordinaire) points out that the single−session
message buffer is actually implemented as a private global variable in the DBMS_PIPE
package body He laments, and I join him, that Oracle did not implement the ability to declare
several message buffers of your own
3.1.2.2 Nontransactional communications
One very important property of the DBMS_PIPE programs is that they are nontransactional This means that they are not bound to the current database transaction, and they will succeed or fail independently of any COMMIT or ROLLBACK processing Transaction independence is one reason why DBMS_PIPE is often used to implement debugging software, since problems in uncommitted transactions can still be logged into database pipes
3.1.2.3 Pipe communications logic
The basic sequence of events for DBMS_PIPE−based communications, follows:
•
Trang 2The sending user loads his private buffer with a "message," which can be composed of multiple items
of various datatypes This is done via successive calls to the PACK_MESSAGE procedure
•
The sending user moves the message from the private buffer into the pipe with the SEND_MESSAGE function
•
The receiving user pulls the message off the pipe into his private buffer using the
RECEIVE_MESSAGE function
•
The receiving user "unpacks" the message items into local variables using the UNPACK_MESSAGE procedure
Figure 3.1 illustrates the architecture and basic logic of pipe−based communications
Figure 3.1: Sending messages between sessions through a database pipe
The post office analogy helps me keep in mind how DBMS_PIPE works Think of the message as something physical (such as a postcard or letter) that moves from one user buffer (mailbox) into the pipe (post office), and then out of the pipe and into another session buffer (mailbox) The pipe itself acts like a first−in−first−out (FIFO) queue −− that is, messages are extracted in the order in which they are put in the queue This
understanding helps clear up the following common points of confusion:
Q: Is the message still in my buffer after calling up SEND_MESSAGE?
A: No, it physically left your session and went into the pipe.
Q: Can two users pull the same message from a pipe using RECEIVE_MESSAGE?
A: No, the first user to make the call has physically removed the message from the pipe.
Q: Can a user pull a specific message from a pipe using RECEIVE_MESSAGE?
A: No, the pipe will always return the next message in the queue.
NOTE: Note that Oracle8's Advanced Queuing features, covered in Chapter 5, Oracle
Advanced Queuing, offer more sophisticated and robust messaging capabilities, which may be
Trang 3used instead of database pipes for more complex applications.
3.1.3 Managing Pipes and the Message Buffer
Use DBMS_PIPE's CREATE_PIPE, REMOVE_PIPE, RESET_PIPE, RESET_BUFFER, PURGE, and UNIQUE_SESSION_NAME programs to create and remove pipes and to perform some additional pipe management operations
3.1.3.1 The DBMS_PIPE.CREATE_PIPE function
The CREATE_PIPE function is used to create a new public or private named database pipe Note that
database pipes can also be created implicitly by the SEND_MESSAGE function Here's the header for this function:
FUNCTION DBMS_PIPE.CREATE_PIPE
(pipename IN VARCHAR2
,maxpipesize IN INTEGER DEFAULT 8192
,private IN BOOLEAN DEFAULT TRUE)
RETURN INTEGER;
Parameters are summarized in the following table
Name Description
pipename Name of the database pipe
maxpipesize Maximum size in bytes of the pipe
private TRUE means pipe is private to user
3.1.3.1.1 Return values
The CREATE_PIPE procedure has a single return value of 0, indicating success This value is returned even if the pipe already existed and can be used by the user
3.1.3.1.2 Exceptions
The program does not raise any package exceptions The following Oracle exceptions are raised if the user attempts to create a pipe that already exists and is private to another user or uses a NULL pipename:
Number Description
ORA−23322 Insufficient privileges to access pipe
ORA−23321 Pipename may not be NULL
3.1.3.1.3 Restrictions
Note the following restrictions on calling CREATE_PIPE:
•
Pipenames are limited to 128 byes in length, are case−insensitive, and cannot contain NLS characters
•
Pipenames must not begin with "ORA$", as these names are reserved for use by Oracle Corporation
3.1.3 Managing Pipes and the Message Buffer 143
Trang 43.1.3.1.4 Example
This example is a function that encapsulates CREATE_PIPE and returns either the Boolean value TRUE, indicating that the pipe can be used by the caller, or FALSE otherwise The function traps the ORA−23322 exception using PRAGMA EXCEPTION_INIT and returns FALSE if this exception is raised
The makepipe function can be found in the dbpipe package discussed in the "Section 3.1.7, "DBMS_PIPE Examples"" section It is created by the dbpipe.sql script
/* Filename on companion disk: dbpipe.sql */*
PACKAGE BODY dbpipe
IS
cannot_use_pipe EXCEPTION;
PRAGMA EXCEPTION_INIT(cannot_use_pipe,−23322);
null_pipename EXCEPTION;
PRAGMA EXCEPTION_INIT(null_pipename,−23321);
/*
|| encapsulates DBMS_PIPE.CREATE_PIPE and returns
|| FALSE if ORA−23322 is raised indicating
|| the pipename is already used and not accessible
|| to the caller
*/
FUNCTION makepipe
(pipename_IN IN VARCHAR2
,maxsize_bytes_IN IN INTEGER DEFAULT 8192
,private_IN IN BOOLEAN DEFAULT TRUE)
RETURN BOOLEAN
IS
call_status INTEGER;
BEGIN
call_status := DBMS_PIPE.CREATE_PIPE
(pipename_IN
,maxsize_bytes_IN
,private_IN);
RETURN call_status = 0;
EXCEPTION
WHEN cannot_use_pipe OR null_pipename
THEN
RETURN FALSE;
END makepipe;
END dbpipe;
The CREATE_PIPE function creates a private pipe by default Private pipes may be used only by sessions connected to the same username (schema) as the pipe's creator or executing stored PL/SQL programs owned
by that schema Public pipes may be accessed by all sessions with execute privileges on DBMS_PIPE Note that CREATE_PIPE is the only way to create a private database pipe Pipes created implicitly by the
SEND_MESSAGE function are always public
Pipes created using CREATE_PIPE should be explicitly removed using the REMOVE_PIPE function
Database pipes are empty upon creation However, if the named database pipe already exists and is available
to the user calling CREATE_PIPE, the function will return 0, but the pipe is not emptied Avoid writing code that assumes that a successful call to CREATE_PIPE results in an empty pipe
The maxpipesize parameter of CREATE_PIPE determines the maximum size in memory of the database pipe This places a limit both on the amount of Oracle shared pool memory and on the maximum size of all
messages the pipe can hold at any time When designing applications that use database pipes, it is important to estimate the number and the size of the messages that the pipe will need to contain, so that maxpipesize can be
Trang 5determined Basically, the objective is to size the pipe as small as possible while making sure that there is plenty of room to handle anticipated message traffic Note that after creation, a pipe's maximum size can be increased using the SEND_MESSAGE function or by destroying and recreating the pipe
3.1.3.2 The DBMS_PIPE.REMOVE_PIPE function
The REMOVE_PIPE function is used to destroy a database pipe and free the memory used by the pipe back to the Oracle shared pool The header for this program is:
FUNCTION DBMS_PIPE.REMOVE_PIPE
(pipename IN VARCHAR2)
RETURN INTEGER;
where the pipename is the name of the database pipe to be removed
3.1.3.2.1 Return values
The REMOVE_PIPE procedure has a single return value of 0, indicating success This value is returned even
if the pipe did not exist
3.1.3.2.2 Exceptions
The program does not raise any package exceptions The following Oracle exceptions are raised if the user attempts to remove a pipe belonging to another user or passes a NULL pipename:
Number Description
ORA−23322 Insufficient privileges to access pipe
ORA−23321 Pipename may not be NULL
3.1.3.2.3 Restrictions
Pipenames must not begin with "ORA$" as these names are reserved for use by Oracle Corporation
3.1.3.2.4 Example
This example is a function that encapsulates REMOVE_PIPE and returns the Boolean value TRUE indicating that the pipe was successfully removed (or did not exist) or FALSE indicating that the pipe exists but cannot
be removed by the caller The function traps the ORA−23322 error using PRAGMA EXCEPTION_INIT and returns FALSE if this exception is raised
The closepipe function can be found in the dbpipe package discussed in the "Section 3.1.7" section and
defined in the dbpipe.sql script.
/* Filename on companion disk: dbpipe.sql */*
PACKAGE BODY dbpipe
IS
cannot_use_pipe EXCEPTION;
PRAGMA EXCEPTION_INIT(cannot_use_pipe,−23322);
null_pipename EXCEPTION;
PRAGMA EXCEPTION_INIT(null_pipename,−23321);
/*
|| encapsulates DBMS_PIPE.REMOVE_PIPE and returns
|| FALSE if ORA−23322 is raised indicating
|| the pipename exists and is not removable
|| by the caller
*/
FUNCTION closepipe
(pipename_IN IN VARCHAR2)
3.1.3 Managing Pipes and the Message Buffer 145