powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / TRIGER или JOB?
19 сообщений из 19, страница 1 из 1
TRIGER или JOB?
    #32143721
Sergey M. Medvedev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здраствуйте!

Есть такая задача:
Внешнее приложение добавляет в некую таблицу записи.
После добавления записи необходимо без задержек ее обработать, т.е. запустить процедуру.

Вопрос: как это правильнее реализовать?

Пробовал JOB с перодом 1 раз в секунду (проверяет наличие записей и запускает процедуру), но получается задержка ~3-4 сек.

Если поставить тригер на insert то увеличивается время добавления записи в таблицу, т.к. процедура долго обрабатывает соотв. записи. В процедуре используются commit и rollback, и это вызывает исключение в тригере.

Внешнее приложение должно быстро добавить запись и забыть про нее. Дальнейшая обработка должна осуществляться Oracle.

Нужно, что-то типа "triger after commit" на таблицу.

Заранее спасибо за ответы.
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32143747
AI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_alert - извещает ждущую сигнала процедуру при commit.
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32143761
Mergen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А почему бы неиспользовать trigger after insert с автономными транзакциями.
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32143828
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У тебя получаются два взаимно противоречивых условия:

- После добавления записи необходимо без задержек ее обработать, т.е. запустить процедуру.
- Внешнее приложение должно быстро добавить запись и забыть про нее.

Ланчей даром не бывает: либо ты выполняешь все действия в одной транзакции, увеличивая ее время, либо выполняешь те же самые действия по заданию. во втором случае ты можешь, к примеру, job создавать прямо в триггере с nextdate=>sysdate, interval=>null. Но надо быть уверенным, что процесс, который будет его выполнять, "увидит" все требуемые данные, т.е. оти будут зафиксированы в сессии, их изменяющей.
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32143843
AI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Denis Popov.

dbms_alert как раз и решает такую задачу. Одна из сессий готовит данные и сигнал, который посылается ждущей сессии при commit'е. Ждущая сессия при получении сигнала просыпается и делает необходимую обработку.

Но я бы все-таки использовал AQ или dbms_job для более гибкой работы. В данном случае, триггер неприемлем.
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32143844
Фотография softy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насколько я знаю, для этого можно использовать так называемые очереди.
Об этом в книге Тома Кайта например пишется.
Он приводит пример готового чужого проекта, что пользователь вводит данные, потом идёт транзакция длинная для обработки, при этом естественно блокируется интерфейс в ожидании(на 45 сек. кажется). Он переделал это через очередь, при этом юзер спокойно вводит данные не ожидая завершения процедуры обработки.
Я так понимаю, это как раз и нужно?
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32143900
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А кто посылает алерт? Всяко не триггер (иначе он же бы полылал commit), а, я думаю, процедура, совершающая обработку? И еще: другая сессия должна постоянно вызвать dbms_alert.waitany или wainone, т.е. заниматься постояным опросом? Если автор топига говорит о 3-4 секундной задержке как о недопустимой, не слишком ли это большие расходы?
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32144001
AI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
waitany/waitone висят и ждут. Их не надо гонять в цикле (хотя можно задавать таймауты ожиданий).
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32144029
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В любом случае в соседней сессии... Вроде получается 2 подхода:
1. Commit -> Signal Alert.
2. Commit -> Submit Job.
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32144061
Sergey M. Medvedev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И что лучше на Ваш взгляд?
Alert или Job?
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32144066
AI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AQ - advanced queuing.
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32144124
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лично я между Alert и Job выбрал вы последнее. Причина- не думаю, что мне бы понравилась сесия, вечно или продолжительное время висящая в ожидании алерта: черт его знает, почему она висит, задание выполняет или просто ждет? Заодно бы читал про AQ.
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32144882
Sergey M. Medvedev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Задержка получается еще больше!!!

Повесил на таблицу тригер:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
DECLARE 
  job_no binary_integer;
  sql_str varchar2( 1024 );
  pragma autonomous_transaction;
BEGIN
    sql_str := 'begin dbms_job.submit(:job_no, :x_what, sysdate, null); commit; end;';
    execute immediate sql_str using out job_no, in 'inbox_routing_job;';

EXCEPTION WHEN others then
  null;
END;


JOB Срабатывает через 9 секунд после выполнения тригера???
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32145037
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
За выполнение JOB'в отвечают соответствующие процессы:
http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96521/jobq.htm

В твоем случае ИМХО можно или поиграться с параметрами JOB_QUEUE_PROCESSES, JOB_QUEUE_INTERVAL, либо делать через алерты. Но учти: для выполнения задания сразу в момент прихода алерта тебе надо обеспечить ситуацию, когда кто-то постоянно его (алерт) ждет. По существу- имитировать работу Job Queues. Заодно представь ситуацию, когда "обработчик" записи- весьма продолжниельна я
процедура:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
create table test (
    test_id number( 9 )
  , entry_date date
  , constraint pk_test primary key(test_id)
)
/
create table test2 (
    test_id number( 9 )
  , entry_date date
  , constraint pk_test2 primary key(test_id)
)
/

create or replace procedure insert_test2 (
  p_test_id number
) as
begin
  insert into test2 (test_id, entry_date)
  values (p_test_id, sysdate);
end;
/
create or replace trigger tbir_test
before insert on test
for each row
begin
  :new.entry_date := sysdate;
end;
/

create or replace trigger tair_test
after insert on test
for each row
declare v_job integer;
  pragma autonomous_transaction;
begin
  dbms_job.submit (
      job => v_job
    , what => 'begin insert_test2('||:new.test_id||'); end;'
    , next_date => sysdate -  1 / 24 / 60 / 60 
    , interval => null
  );
  commit;
end;
/
begin
  for i in  1 .. 20  loop
    insert into test(test_id) values (i);
  end loop;
end;
/

select t.test_id
     , t.entry_date t_entry_date
     , t2.entry_date t2_entry_date
from test t
   , test2 t2
where  1 = 1 
  and t.test_id = t2.test_id
/
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32149716
Sergey M. Medvedev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вы говорите использовать AQ!
т.е. тригер при insert'е помещает задание в очередь с помощью ENQUEUE
а кто это задание считывать будет (DEQUEUE)?
Как узнать, что в очередь что-то добавилось?

И еще, на каждую запись должна запускаться соотв. процедура, и если она ее долго обрабатывает, то остальные записи не должны ждать завершения обработки предыдущей. Т.е. их надо пускать паралельно???

У кого какие мысли по этому поводу???
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32149717
Фотография Oracle X-pert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Esli ne ustraivaet ni to, no drugoe, to , moget, nado by izmenit' podhod k resheniu tvoei zadachi??
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32149721
Виктор
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня в проекте почти то, о чем ты говоришь, сделано через Alert'ы.
Человек делает проводку товарного документа - при этом в табличку пишется соответств. инфа и посылается алерт. На серваке висит прога, которая ловит этот алерт и запускает нужные процедурины (скорость обработки зависит от многих параметров). И так по циклу. Прога-обработчик выделена отдельно для того, чтобы попутно писать-читать логи, а вообще можно и прям в оракле всё сделать. Т.о. реализована обычная очередь. Параллельности обработки у меня нет, т.к. сложно при одновременной проводке двух док-тов проверять остатки, писать кэши дебиторки и т.п.
Конечно, можно переделать на AQ, но как говорится - работает, не трожь :-)
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32149733
Фотография Oracle X-pert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alert, AQ, CORBA etc..
But check Your buisiness-logic!
...
Рейтинг: 0 / 0
TRIGER или JOB?
    #32149902
Sergey M. Medvedev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ура, получилось!!!
Использую AQ. При помещении в очередь проблем нет.
Подскажите как теперь их оттуда корректно забирать.

Вот этот код работает, но мне надо, чтоб он постоянно висел.
(здесь ждет 20 секунд)

Для этого я убрал параметр v_DequeueOptions.wait, но кто должен запустить эту процедуру на выполнение???

Может в триггере на StartUp???

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
DECLARE
  v_Message InboxObj;
  v_DequeueOptions DBMS_AQ.DEQUEUE_OPTIONS_T;
  v_MessageProperties DBMS_AQ.MESSAGE_PROPERTIES_T;
  v_MsgID RAW( 16 );

  e_QTimeOut EXCEPTION;
  PRAGMA EXCEPTION_INIT(e_QTimeOut, - 25228 );
BEGIN

  BEGIN
    LOOP
      v_DequeueOptions.wait :=  20 ;
      DBMS_AQ.DEQUEUE(
        queue_name => 'InboxQ',
        dequeue_options => v_DequeueOptions,
        message_properties => v_MessageProperties,
        payload => v_Message,
        msgid => v_MsgID);

      v_Message.Process;
    END LOOP;
  EXCEPTION
    WHEN e_QTimeOut THEN
      NULL;
  END;

  COMMIT;
END;
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / TRIGER или JOB?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]