DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

DBMS_PIPE для коммуникации между сессиями

Пакет DBMS_PIPE обеспечивает незащищенный механизм для обмена сообщениями между сеансами. Такой обмен считают незащищенным, потому что сообщения канала могут быть потеряны, если экземпляр базы данных отказывает завершает свою работу прежде, чем сообщения будут обработаны. Advanced Queues - лучший механизм, когда требуется безопасный обмен сообщениями и большая гибкость.
Есть два типа каналов:
Неявные Каналы. Они создаются автоматически, когда сообщение отправлено с неизвестным pipename при использование функции SEND_MESSAGE. Неявные каналы автоматически исчезают, когда они пусты.
Явные Каналы - Они создаются, используя функцию CREATE_PIPE. Явно создаваемые каналы должны быть удалены функцией REMOVE_PIPE.
Есть два уровня безопасности для каналов:
Общедоступные Каналы. Они доступны любым пользователем с правами EXECUTE на пакет DBMS_PIPE. Неявные каналы всегда общедоступны, но они могут также быть созданы явно, при помощи функции CREATE_PIPE с приватным параметром, установленным в FALSE.
Частные Каналы. Они доступны только сеансам с тем же самым ownerid как создатель канала, PL/SQL программам, принадлежащим создателю канала или пользователям с правами SYSDBA.
Следующий пример использует функцию CREATE_PIPE, для создания явных общедоступных и частных каналов. V$DB_PIPES предоставляет информацию о каналах.
DECLARE
l_result INTEGER;
BEGIN
-- Explicit public pipe.
l_result := DBMS_PIPE.create_pipe(pipename => 'explicit_public_pipe',
private => FALSE);
-- Explicit private pipe.
l_result := DBMS_PIPE.create_pipe(pipename => 'explicit_private_pipe');
END;
/
PL/SQL procedure successfully completed.
COLUMN name FORMAT A30
SELECT * FROM v$db_pipes;
OWNERID NAME TYPE PIPE_SIZE
---------- ------------------------------ ------- ----------
55 EXPLICIT_PRIVATE_PIPE PRIVATE 358
EXPLICIT_PUBLIC_PIPE PUBLIC 357
2 rows selected.
SQL>
Следующий пример использует функцию REMOVE_PIPE, чтобы удалить каналы, созданные ранее.
DECLARE
l_result INTEGER;
BEGIN
-- Explicit public pipe.
l_result := DBMS_PIPE.remove_pipe(pipename => 'explicit_public_pipe');
-- Explicit private pipe.
l_result := DBMS_PIPE.remove_pipe(pipename => 'explicit_private_pipe');
END;
/
PL/SQL procedure successfully completed.
COLUMN name FORMAT A30
SELECT * FROM v$db_pipes;
no rows selected
SQL>
Сообщения упаковываются в буфер, одна переменная за один раз, используя процедуру PACK_MESSAGE. Как только сообщение заполнено, оно отправляется, используя функцию SEND_MESSAGE. Сообщения могут быть получены при помощи функции RECEIVE_MESSAGE и распакованы, одна переменная за один раз, используя процедуру UNPACK_MESSAGE. Следующий код создает пакет (message_api), который содержит две процедуры (отправка и получение), которые позволяют сообщениям быть отправленными и полученными при помощи общедоступного канала.
CREATE OR REPLACE PACKAGE message_api AS
PROCEDURE send (p_number IN NUMBER,
p_text IN VARCHAR2,
p_date IN DATE DEFAULT SYSDATE);
PROCEDURE receive;
END message_api;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY message_api AS
PROCEDURE send (p_number IN NUMBER,
p_text IN VARCHAR2,
p_date IN DATE DEFAULT SYSDATE) AS
l_status NUMBER;
BEGIN
DBMS_PIPE.pack_message(p_number);
DBMS_PIPE.pack_message(p_text);
DBMS_PIPE.pack_message(p_date);
l_status := DBMS_PIPE.send_message('message_pipe');
IF l_status != 0 THEN
RAISE_APPLICATION_ERROR(-20001, 'message_pipe error');
END IF;
END;
PROCEDURE receive AS
l_result INTEGER;
l_number NUMBER;
l_text VARCHAR2(32767);
l_date DATE;
BEGIN
l_result := DBMS_PIPE.receive_message (
pipename => 'message_pipe',
timeout => DBMS_PIPE.maxwait);
IF l_result = 0 THEN
-- Message received successfully.
DBMS_PIPE.unpack_message(l_number);
DBMS_PIPE.unpack_message(l_text);
DBMS_PIPE.unpack_message(l_date);
DBMS_OUTPUT.put_line('l_number: ' || l_number);
DBMS_OUTPUT.put_line('l_text : ' || l_text);
DBMS_OUTPUT.put_line('l_date : ' || l_date);
ELSE
RAISE_APPLICATION_ERROR(-20002, 'message_api.receive was unsuccessful. Return result: ' || l_result);
END IF;
END receive;
END message_api;
/
SHOW ERRORS
Чтобы протестировать пакет, выполните следующий код в одном сеансе. Будет казаться, что сеанс зависнет, ожидая сообщения, которое будет считано из канала.
CONN test/test
SET SERVEROUTPUT ON
EXEC message_api.receive;
В другом сеансе выполните следующий код, чтобы отправить сообщение.
CONN test/test
BEGIN
message_api.send(p_number => 12345,
p_text => 'This is a test.',
p_date => SYSDATE);
END;
/
Вызов процедуры в первом сеансе сразу возвращается, распечатывая содержание сообщения, как показано ниже.
SQL> CONN test/test
Connected.
SQL> SET SERVEROUTPUT ON
SQL> EXEC message_api.receive;
l_number: 12345
l_text : This is a test.
l_date : 20-NOV-2005 13:35:57
PL/SQL procedure successfully completed.
SQL>







jAntivirus
 


Металлопластиковые окна и окна rehau большой опыт работ. . Капитальный ремонт двигателя ваз 2108 стоимость