|
Программирование >> Oracle
1566 Приложение А Тогда соответствующий триггер будет иметь вид: tkyte@TKYTE816>create table t (x int) ; Table created. tkyte@TKYTE816>create or replace trigger t trigger 2 after insert or update of x on t for each row 3 declare 4 l job number; 5 begin 6 dbms job.submit(l job, background alert(JOB);); 7 insert into alert messages 8 (job id, alert name, message) 9 values 10 (l job, MyAlert, X вT имеет значение :new.x); 11 end; 12 / Trigger created. И будет обеспечивать передачу сигнала фоновым процессом после фиксации. При этом: сигналы пос1лаются в рамках транзакций; приоритетные процессы (интерактивные приложения) в очередь не выстраиваются. Недостаток этого подхода в том, что задания могут выполняться не сразу; может пройти некоторое время, прежде чем сигнал будет послан. Во многих случаях это приемлемо (важно уведомить ожидающие процессы о произошедшем событии, даже если и с небольшим опозданием). Средстварасширеннойподдержки очередей (advanced queues- AQ) также обеспечивают хорошо масштабируемый способ уведомления о событиях в базе данных. Использовать их сложнее, чем средства пакета DBMS ALERT, но при этом обеспечивается большая гибкость. Неоднократная передача сигнала в сеансе Теперь попытаемся ответить на вопрос, что произойдет, если послать одноименный сигнал в приложении несколько раз, а затем зафиксировать транзакцию? Сколько сигналов фактически будет послано? В данном случае ответ простой: один. Работа пакета DBMS ALERT аналогична механизму передачи сигналов в ОС UNlX. В UNIX сигналы посылаются для уведомления процессов о событиях в операционной системе. Пример такого события - I/O is ready (готовность к вводу-выводу), которое означает, что один из открытых файлов (или сокетов и т.п.) готов для продолжения операций ввода-вывода. Этот сигнал можно, например, использовать при создании сервера на основе протоколов TCP/IP. Операционная система уведомит вас, когда в одном из открытых сокетов появятся данные, ожидающие чтения; то есть не придется постоянно опрашивать состояние каждого сокета, проверяя, нет ли в нем данных для чтения. Если ОС пять раз определила, что в сокете есть данные для чтения, но у нее не было возможности уведомить об этом приложение, она не будет повторять сообщение пять раз. Вы полу- Пакеты DBMS ALERT и DBMS PIPE 1567 чите уведомление о событии из сокета X можно читать , но не всю хронологию предыдущих событий по этому сокету. Пакет DBMS ALERT работает точно так же. Возвращаясь к рассматриваемому примеру, можно выполнить фрагмент кода, регистрирующий сеанс на уведомление о событии и вызывающий процедуру WAITONE в ожидании этого события. В другом сеансе выполняем: tkyte@TKE816> begin 2 for i in 1 10 loop 3 dbms alert.signal(MyAlert, Сообщение i); 4 end loop; 5 end; PL/SQL procedure successfully completed. tkyte@TKYTE816> commit; Gommit complete. И в первом окне получаем результат: Сообщение события: сообщение 10 PL/SQL procedure successfully completed. Послано будет только последнее сообщение, о котором мы сигнализировали. Промежуточных сообщений никто никогда не увидит. Следует учитывать, что пакет DBMS ALERT будет, как и задумано создателями, отбрасывать все предыдущие сообщения сеанса. С помощью этого пакета нельзя отправить в транзакции последовательность сообщений - это только механизм сигнализации. Он позволяет уведомить клиентское приложение, что нечто произошло . Если вы предполагаете, что каждое событие, о котором вы уведомляли с помощью сигнала, будет получено всеми заинтересованными сеансами, - вас ждет разочарование (написанный на основе этого предположения код будет скорее всего ошибочен). Для решения этой проблемы можно использовать пакет DBMS JOB, если для уведомления о каждом событии применять его средства. Однако можно использовать и другую технологию. С помощью средств расширенной поддержки очередей (которые в этой книге не рассматриваются) справиться с этой задачей намного проще. Передача многочисленных сигналов несколькими сеансами до вызова процедуры ожидания Это последний вопрос: что произойдет, если сигнал будет послан несколькими сеансами после того, как на него поступил запрос, но прежде, чем вызвана процедура ожидания? Аналогичный вопрос: что произойдет, если между вызовами процедур ожидания несколько сеансов пошлют сигнал? Как и в случае многократного вызова DBMS ALERT.SIGNAL в одном сеансе, запоминается только последний сигнал, и именно о нем получат уведомление сеансы. В этом можно убедиться, добавив команду PAUSE к используемому в примерах сценарию SQL*Plus: 1568 Приложение А begin dbms alert.register(MyAlert); end; pause Затем в других сеансах вызовите процедуры DBMS ALERT.SIGNAL с уникальн:-ми сообщениями (чтобы их можно было различать) и зафиксируйте каждое сообщение. Например, измените представленный ранее простой цикл следующим образом: tkyte@TKYTE816> begin 2 for i in 1 .. 10 loop 3 dbms alert.signal(MyMert, Сообщение i); 4 commit; 5 end loop; 6 end; PL/SQL procedure successfully completed. После этого в исходном сеансе просто нажмите клавишу Enter, и блок кода, в1-вающий процедуру WAITONE, будет выполнен. Поскольку ожидаемый сигнал уже послан, этот блок кода немедленно завершит работу и выдаст строку, свидетельствующую о получении последнего сообщения (о чем оповестил сигнал). Все промежуточные сообщения других сеансов потеряны, как и было задумано создателями пакета. Итак, пакет DBMS ALERT подходит для тех случаев, когда необходимо уведомить о событиях в базе данных множество клиентов. Об этих именованных событиях должно сообщать как можно меньше сеансов, из-за существенных проблем с очередностью доступа к процедурам пакета DBMS ALERT. Поскольку неоднократные сообщения теряются, пакет DBMS ALERT подходит в качестве средства уведомления о собггии. Его можно использовать для уведомления клиента, например, об изменении данных в таблице T, но попытка использовать его для уведомления об изменениях в отдельных строках таблицы T закончится неудачей (поскольку сохраняется только последнее сообщение). Пакет DBMS ALERT очень прост в использовании и практически не требует настройки. Пакет DBMS PIPE DBMS PIPE - это стандартный пакет, обеспечивающий обмен данными между двумя сеансами. Это средство межпроцессного взаимодействия. Один сеанс может записывать сообщение в программный канал, а другой - читать это сообщение. В ОС UNIX аналогичный механизм реализован в виде именованного канала операционной системы. С помощью именованных каналов можно обеспечить запись данных одним процессом для другого. Пакет DBMS PIPE, в отличие от DBMS ALERT, - это пакет, работающий в режиме реального времени. При вызове функции SEND MESSAGE немедленно посылается сообщение. Сервер не ждет выполнения оператора COMMIT; передача сообщения выполняется вне транзакции. Это позволяет использовать пакет DBMS PIPE в тех случаях, когда DBMS ALERT не подходит (и наоборот). С помощью пакета
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |