SA-Concurrent request scheduling explained

Concurrent request scheduling explained

Concurrent request scheduling explained

It’s quite an interesting way that’s used to implement concurrent request schedules in Oracle Applications. In this post I’ll describe how “Periodic” and “On Specific Day” type of schedules are stored in the Database and if you will be patient enough to read all the story, I’ll give you a query that can be used to report all the request schedules in the environment.

I’ll pay attention to the repeating schedules only as requests submitted for one-time execution are not too interesting, basically, they use thefnd_concurrent_requests.requested_start_date field to store the time the request has to be executed. This field is used in repeating schedules to specify the time of next execution.

There are just 2 normal types of repeating schedules.<Defining a 'periodic' schedule

Periodic – the request is submitted for execution in pre-defined intervals of specified number of months, weeks, days, hours or minutes.<Definig a 'on Specific Days' schedul>.

On Specific Days – user can choose exact dates of month or days of week when the request will be executed. There’s an option to schedule requests for the last day of months too.

There’s also a 3rd option – Advanced – this is a special option that implements possibility to run requests based on schedules, that depend on different financial calendars and financial periods. This kind of scheduling is rarely used as it’s available in few Applications products only, e.g. GL. These schedules are managed by Scheduler/Prereleaser Concurrent Manager.

There are 2 tables invoved in storing the information about schedules:fnd_concurrent_requests that stores all basic information about concurrent requests including the next time the request is scheduled for, and fnd_conc_release_classes that stores information about the schedules. Both tables can be joined by release_class_id.

The fields we are interested in are:
fnd_conc_release_classes.CLASS_TYPE
 – contains value ‘P’ for “Periodic” schedules, “S” – for “on Specific Days” schedules and “X” – for advanced schedules.
fnd_conc_release_classes.DATE1 – 
start date of the schedule (“Start at” field in the form)
fnd_conc_release_classes.DATE2 – 
end date of the schedule (“End at” field in the form) –this information is doubled in fnd_concurrent_requests.resubmit_end_date.

fnd_conc_release_classes.CLASS_INFO – this is the most interesting field as it contains all the information needed for reschedulingThe format of the field depends on the type of schedule.

“PERIODIC” schedule

In case of Periodic schedule fnd_conc_release_classes.CLASS_INFO field contains values like “2:D:S” or X:Y:Z where:

  • X – number of months/weeks/days/hours/minutes the request has to be rescheduled from prior run.
  • Y – contains a single letter representing units
    • “M” – months;
    • “D” – days;
    • “H” – hours;
    • “N” – minutes;
    • (there is no representation of “weeks” option. If you specify interval in weeks, it’s automatically calculated and stored in “days”).
  • Z – contains a single letter to represent if the rescheduling has to be done from start or from completion of the prior run
    • S – from the start of the prior run;
    • C – from the completion of the prior run.

Some samples:

  • 30:N:S – Repeat every 30 minutes from the start of the prior run
  • 5:N:C – Repeat every 5 minutes from the completion of the prior run
  • 12:H:S – Repeat every 12 hours from the start of the prior run

It’s interesting that information about intervals of periodic schedules is duplicated infnd_concurrent_requests table fields RESUBMIT_INTERVAL, RESUBMIT_INTERVAL_TYPE_CODE and RESUBMIT_INTERVAL_UNIT_CODE. I haven’t yet found why’s that so.

“ON SPECIFIC DAY” schedule

In case of on Specific Day schedule fnd_conc_release_classes.CLASS_INFO field contains values like “000010000000000000000000000000010000000” – a 39 character value consisting of 0 and 1. The idea is that the placement of 1-s represent the options selected through form:

  • 1-s at places 1 to 31 – represent dates, when request has to be run, eg, if the 10th character is “1” – the request is scheduled to run on 10th day of each month;
  • character “1” at the 32nd position – specifies that the request has to be run at the last day of each month;
  • 1-s at places 33 to 39 – specifies days of week (Sunday – Saturday)the request has to be run. if the 33rd character is “1” – the request is scheduled to run each Sunday, if 34th – on Monday and so on.

Some samples:

  • 000000000000000000000000000000000000001 – Days of week: Sa
  • 111111111000000000000000000000000111110 – Dates: 1 2 3 4 5 6 7 8 9. Days of week: Mo Tu We Th Fr
  • 000000000000000000000000000000010000000 – Last day of month

Reporting all schedules

Using the information given above I wrote a “small” query to provide a report like this:

Reporting all schedules

Reporting all schedules

The query was tested in Oracle Applications versions 11.5.9, 11.5.10.1, 12.0.1 and 12.0.4 so there’s a good chance it will work on others as well. The performance of the query was OK.  but I have to say – test/analyze it before running in productio.

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
select r.request_id,
        p.user_concurrent_program_name || case
          when p.user_concurrent_program_name = 'Report Set' then
           ( select ' - ' || s.user_request_set_name
              from fnd_request_sets_tl s
             where s.application_id = r.argument1
               and s.request_set_id = r.argument2
               and language = 'US' )
          when p.user_concurrent_program_name = 'Check Periodic Alert' then
           ( select ' - ' || a.alert_name
              from alr_alerts a
             where a.application_id = r.argument1
               and a.alert_id = r.argument2
               and language = 'US' )
        end concurrent_program_name,
        case
          when p.user_concurrent_program_name != 'Report Set' and
               p.user_concurrent_program_name != 'Check Periodic Alert' then
           r.argument_text
        end argument_text,
        r.requested_start_date next_run,
        r.hold_flag on_hold,
        decode(c.class_type,
               'P' ,
               'Periodic' ,
               'S' ,
               'On Specific Days' ,
               'X' ,
               'Advanced' ,
               c.class_type) schedule_type,
        case
          when c.class_type = 'P' then
           'Repeat every ' ||
           substr(c.class_info, 1, instr(c.class_info, ':' ) - 1) ||
           decode(substr(c.class_info, instr(c.class_info, ':' , 1, 1) + 1, 1),
                  'N' ,
                  ' minutes' ,
                  'M' ,
                  ' months' ,
                  'H' ,
                  ' hours' ,
                  'D' ,
                  ' days' ) ||
           decode(substr(c.class_info, instr(c.class_info, ':' , 1, 2) + 1, 1),
                  'S' ,
                  ' from the start of the prior run' ,
                  'C' ,
                  ' from the completion of the prior run' )
          when c.class_type = 'S' then
           nvl2(dates.dates, 'Dates: ' || dates.dates || '. ' , null ) ||
           decode(substr(c.class_info, 32, 1), '1' , 'Last day of month ' ) ||
           decode(sign(to_number(substr(c.class_info, 33))),
                  '1' ,
                  'Days of week: ' ||
                  decode(substr(c.class_info, 33, 1), '1' , 'Su ' ) ||
                  decode(substr(c.class_info, 34, 1), '1' , 'Mo ' ) ||
                  decode(substr(c.class_info, 35, 1), '1' , 'Tu ' ) ||
                  decode(substr(c.class_info, 36, 1), '1' , 'We ' ) ||
                  decode(substr(c.class_info, 37, 1), '1' , 'Th ' ) ||
                  decode(substr(c.class_info, 38, 1), '1' , 'Fr ' ) ||
                  decode(substr(c.class_info, 39, 1), '1' , 'Sa ' ))
        end schedule,
        c.date1 start_date,
        c.date2 end_date,
        c.class_info
   from fnd_concurrent_requests r,
        fnd_conc_release_classes c,
        fnd_concurrent_programs_tl p,
        ( SELECT release_class_id,
                substr( max (SYS_CONNECT_BY_PATH(s, ' ' )), 2) dates
           FROM ( select release_class_id,
                        rank() over(partition by release_class_id order by s) a,
                        s
                   from ( select c.class_info,
                                l,
                                c.release_class_id,
                                decode(substr(c.class_info, l, 1),
                                       '1' ,
                                       to_char(l)) s
                           from ( select level l from dual connect by level <= 31),
                                fnd_conc_release_classes c
                          where c.class_type = 'S' )
                  where s is not null )
         CONNECT BY PRIOR
                     (a || release_class_id) = (a - 1) || release_class_id
          START WITH a = 1
          group by release_class_id) dates
  where r.phase_code = 'P'
    and c.application_id = r.release_class_app_id
    and c.release_class_id = r.release_class_id
    and nvl(c.date2, sysdate + 1) > sysdate
    and c.class_type is not null
    and p.concurrent_program_id = r.concurrent_program_id
    and p.application_id = r.program_application_id
    and p.language = 'US'
    and dates.release_class_id(+) = r.release_class_id
  order by on_hold, next_run;

I know there are some interesting lines in this query that might need some explanation, but as that is not directly connected to the topic of this post I’ll provide explanation in comments if you will ask for it.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sa-token可以通过以下配置来校验token: 1. 配置token名称:在yml配置文件中,可以通过设置`sa-token.token-name`来指定token的名称,例如`sa-token.token-name: X-Token`\[1\]。 2. 配置token有效期:可以通过设置`sa-token.timeout`来指定token的有效期,单位为秒,默认为30天,可以设置为-1代表永不过期,例如`sa-token.timeout: 2592000`\[1\]。 3. 配置token临时有效期:可以通过设置`sa-token.activity-timeout`来指定token的临时有效期,即在指定时间内无操作就视为token过期,单位为秒,默认为-1,表示不设置临时有效期,例如`sa-token.activity-timeout: -1`\[1\]。 4. 配置是否允许同一账号并发登录:可以通过设置`sa-token.is-concurrent`来指定是否允许同一账号并发登录,为true时允许一起登录,为false时新登录会挤掉旧登录,例如`sa-token.is-concurrent: true`\[1\]。 5. 配置是否共用一个token:可以通过设置`sa-token.is-share`来指定在多人登录同一账号时,是否共用一个token,为true时所有登录共用一个token,为false时每次登录会新建一个token,例如`sa-token.is-share: true`\[1\]。 6. 配置是否输出操作日志:可以通过设置`sa-token.is-log`来指定是否输出操作日志,为true时输出操作日志,为false时不输出操作日志,例如`sa-token.is-log: false`\[1\]。 7. 配置是否使用cookie保存token:可以通过设置`sa-token.is-read-cookie`来指定是否使用cookie保存token,为true时使用cookie保存token,为false时不使用cookie保存token,例如`sa-token.is-read-cookie: false`\[1\]。 8. 配置是否使用head保存token:可以通过设置`sa-token.is-read-head`来指定是否使用head保存token,为true时使用head保存token,为false时不使用head保存token,例如`sa-token.is-read-head: true`\[1\]。 通过以上配置,sa-token可以根据配置的规则来校验token的有效性。 #### 引用[.reference_title] - *1* [最简单的权限验证实现——使用Sa-Token进行权限验证](https://blog.csdn.net/lp840312696/article/details/127072424)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [探索 Sa-Token (一) SpringBoot 集成 Sa-Token](https://blog.csdn.net/weixin_38982591/article/details/126764928)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值