powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Механизм заявок. Как заставить джоб начать работать раньше времени?
17 сообщений из 17, страница 1 из 1
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39493439
anvano
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть некий джоб, который разгребает очередь неких заявок.

Проблема в том, что джоб выполняется по расписанию. Допустим, раз в минуту.
Запускается и обрабатывает накопившиеся к моменту запуска заявки.
Если заявок нет - отрабатывает вхолостую и завершается.

Но получается, если заявка поступила после того, как джоб уже закончил работу - она целую минуту висит "В очереди".
Вот этого простоя до очередного запуска джоба хотелось бы каким-то образом избежать.

Можно конечно уменьшить период запуска джоба. Запускать раз в секунду, например. Но на это ДБА как-то косо смотрит
(учитывая, что такой джоб не один в базе - его можно понять).

Есть-ли какое-то стандартное архитектурное решение у данной проблемы без использования AQ ?

Требования следующие:

1) Разгребать очередь должен строго один процесс.
(Т.е. спавнить для каждой заявки свой асинхронный процесс в момент постановки - не прокатит)

2) Когда заявок нет - не хотелось бы, чтобы процесс слишком часто запускался, чтобы проверить наличие заявок.
3) Когда заявка поступила, хочется, чтобы процесс как можно быстрее начал её обрабатывать.
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39493452
Valergrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvano,

на всякий случай сообщу что ставить время срабатывания джоба "раз в секунду" не имеет никакого смысла - можете сами убедиться что запускаться он все равно будет примерно раз в 5 секунд, что связано с механизмом того как оракл запускает джобы.
В вашем же случае не понимаю почему не сделать постоянно висящий процесс, который раз в секунду или сколько там просыпается и смотрит не появилось ли новых заявок. Засыпать можно с помощью dbms_lock.sleep, это не должно аффектить перформанс.
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39493464
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvanoКогда заявка поступила, хочется, чтобы процесс как можно быстрее начал её обрабатывать.Автономка:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
    for cJob in
    ( select job, next_date, broken from user_jobs
        where what = fJobWhat
        for update
    ) loop
      dbms_job.broken(cJob.job, false, least(sysdate + interval '1' second, cJob.next_date));
      commit;
      return;
    end loop;
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39493518
проходил мимо...
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,

Сорри, а почему не просто .run ?
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39493551
anvano
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВ вашем же случае не понимаю почему не сделать постоянно висящий процесс, который раз в секунду или сколько там просыпается и смотрит не появилось ли новых заявок. Засыпать можно с помощью dbms_lock.sleep, это не должно аффектить перформанс.


Пока на этом остановились.
Но в этом решении есть побочные эффекты.
Для продакшена - оно в принципе нормально работает.
Но для инстансов разработки и тестирования - не очень, т.к. постоянно висящий процесс лочит используемые пакеты (DDL locks) и не дает накатывать некоторые пакеты. Приходится постоянно помнить, что где-то там висит джоб, который надо остановить.
Хотя всё равно вспоминаешь об этом только когда пытаешься скомпилировать какой-то пакет и он залипает.


Попробую еще решение на базе Elic`a , чтобы в момент постановки заявки толкать некую процедурину в автономной транзакции, которая изменит время старта нужного джоба на ближайшие несколько секунд.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
BEGIN
  dbms_scheduler.set_attribute(
    name      => 'JB_TEST',
    attribute => 'start_date',
    value     => SYSDATE + INTERVAL '1' SECOND
  );
END;
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39493597
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
проходил мимо...Elic,

Сорри, а почему не просто .run ?Даже не знаю, зачем объяснять разницу между одной и несколькими сессиями.
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39494013
Фотография Vladimir Filin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvanoТребования следующие:
1) Разгребать очередь должен строго один процесс.
2) Когда заявок нет - не хотелось бы, чтобы процесс слишком часто запускался, чтобы проверить наличие заявок.
3) Когда заявка поступила, хочется, чтобы процесс как можно быстрее начал её обрабатывать.
Может и job не нужен? Похоже на захват изменений данных в таблицах. Недавно тема была 1266481
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39494037
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvanoбез использования AQа чем AQ не угодил?
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39494042
XMLer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-anvanoбез использования AQа чем AQ не угодил?
+1
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39494073
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотрите возможности пакета
DBMS_ALERTDBMS_ALERT supports asynchronous notification of database events (alerts). By
appropriate use of this package and database triggers, an application can notify itself
whenever values of interest in the database are changed.
Может быть это как раз для вашего случая...
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39494076
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL*PlusМожет быть это как раз для вашего случая...Хрен редьки не слаще.
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39494397
anvano
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-anvanoбез использования AQа чем AQ не угодил?

Не угодил тем, что я скорее всего не умею его готовить правильно.

Сколько раз пробовал - постоянно какие-то проблемы. Чаще всего проблемы возникают при нестабильной сети.
В самый неожиданный момент отваливаются подписчики и перестают получать уведомления. При этом внешне всё хорошо - типа всё работает, но при этом ничего не работает. А диагностировать, что "уже не работает", со стороны подписчика практически нереально.
Приходилось даже костыли делать типа принудительного перезапуска подписчиков по расписанию.

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

Признаться честно - после нескольких факапов со стороны AQ, мы просто сдались и перешли на понятный, простой и железобетонный велосипед собственного производства.
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39494478
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а если повесить триггер на добавление записи в таблицу заявок?
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39497810
Есть за что погнобить?

Код: plsql
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.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
drop table job_next_run purge;
create table job_next_run(job_name varchar2(50 char) not null, next_run_date date not null);

begin
    for i in (select * from user_scheduler_jobs where job_name = 'JOB_RUNER')
    loop
        sys.dbms_scheduler.drop_job(i.job_name);
    end loop i;
end;
/
begin
    sys.dbms_scheduler.create_job
    (
        job_name            => 'JOB_RUNER',
        job_type            => 'PLSQL_BLOCK',
        job_action          => '
declare
    procedure run_job(p_job_name varchar2)
    is
        pragma autonomous_transaction;
        type t_rowid_list is table of rowid;
        v_rowid_list t_rowid_list;
        v_cur sys_refcursor;
    begin
        -- Лочим со skip и удаляем записи, дающие основания для запуска жоба сейчас.
        open v_cur for select rowid from job_next_run where next_run_date <= sysdate and job_name = p_job_name for update skip locked;
        loop
            fetch v_cur bulk collect into v_rowid_list limit 1000;
            exit when v_rowid_list.count() = 0;
            forall v_idx in indices of v_rowid_list
                delete from job_next_run where rowid = v_rowid_list(v_idx);
            exit when v_cur%notfound;
        end loop;
        close v_cur;

        -- Инициируем запуск жоба.
        sys.dbms_scheduler.run_job(p_job_name, use_current_session => false);

        -- В случае успеха - коммитим удаление основания для запуска жоба.
        commit;
    exception
        when others then
            -- В случае - ошибки откатываемся.
            rollback;
            
            -- Если ошибка вне списка ожидаемых, логгируем её.
            if sqlcode not in (-27478 /*job is running*/  ) then
                event_api.log_event
                (
                    p_event_text => sqlerrm,
                    p_event_type => ''E'',
                    p_autonomous =>  true
                );
            end if;
    end;
begin
    for i in (select distinct job_name from  job_next_run where next_run_date <= sysdate)
    loop
        run_job(i.job_name);
    end loop;
end;
',
        number_of_arguments => 0,
        start_date          => to_date(null),
        repeat_interval     => 'Freq=Secondly;Interval=1',
        end_date            => to_date(null),
        job_class           => 'DEFAULT_JOB_CLASS',
        enabled             => true,
        auto_drop           => false,
        comments            => 'Жоба для внепланого запуска других жоб'
    );
end;
/
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39498305
Pavel_PV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кроик Семёна если повесить триггер на добавление записи в таблицу заявок?
+1, самое логичное с виду? На триггер посадить процедуру которая будет обрабатывать заявки, собственно та которую дергает джоб.
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39498449
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
anvano-2-пропущено...
а чем AQ не угодил?проблемы возникают при нестабильной сетичто поменяется в случае замены таблицы с типом велосипед на таблицу с типом aq и заменой джоба по расписанию на по событию?
...
Рейтинг: 0 / 0
Механизм заявок. Как заставить джоб начать работать раньше времени?
    #39502966
Sergei.Agalakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не устраивает Oracle AQ - используйте внешнюю очередь сообщений. Море их, и задача по описанию ровно для них.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Механизм заявок. Как заставить джоб начать работать раньше времени?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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