BatchJob - BatchJob still running when is server stopped - spring

When the BJ is currently RUNNING and if server is STOPPED, the BATCH JOB status in Spring Batch Admin still shows its RUNNING even after the server is stopped, it needs to be FAILED
Please help on this? Do we need to handle it manually or we can achieve it out of the box.
Need help on this?

the job repository (database implementation) reflects the last 'known' state. so, in the case where the job was running and the JVM crashed, then it will never be updated in the database.
in the event of the database being 'out-of-sync' with the JVM, then the process needs to be a manual one, there doesn't appear to be an out of the box solution for it. the simplest solution would be to execute a script on startup that checked the batch tables for any RUNNING jobs and then 'failed' them.
update batch_job_execution set STATUS = 'FAILED', EXIT_CODE = 'FAILED', EXIT_MESSAGE = 'FORCED UPDATE' where job_execution_id in (select job_execution_id from batch_job_execution where status = 'RUNNING');
one thing you will want to consider in this situation is if the JobRepository tables, and the jobs associated with them, are shared with another JVM. in this case, you may wish to do a pass that also evaluates if the job is still running beyond the maximum runtime of any history it has. (a subselect with max() end_time - create_time for the same job_name)

Related

Oracle scheduler JOBS: get argument_value used in a specific job instance

I have a Oracle Scheduler Job configured in my DB 19c. This is as event-based job, with a queue table created used in this process.
I need to analyse a possible problem in one of this executions. In DBA_SCHEDULER_JOB_LOG table I have the instance and a JOB_SUBNAME called SCHED$_EVTPARINST_89121.
Although I don't have DBA privileges, I have two questions:
How can I get the parameters values passed to this scheduler Job instance?
How can I get the Log (history) of enqueue messages, with enqueue date and set_job_argument_value associated to each enqueue message?
I've tried to check in Oracle documentation (https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/scheduling-jobs-with-oracle-scheduler.html#GUID-E9B234FF-C7F3-44B0-AEC8-A997353C414F or https://docs.oracle.com/database/121/ARPLS/d_aq.htm#ARPLS004) without success.
Thanks.

Spring Boot Task Scheduling - rerun a task conditionally

I have an application where users can schedule to run reports at a certain time. The data for the reports is populated by an overnight batch process which might get delayed (occasionally) due to upstream issues. When that happens, the reports need to be re-tried every few minutes until we have data. I have a db table that records the status of the batch, there will be a row in that table when the data becomes available for this report.
I am thinking along these lines: When the data is not available, the task will cancel itself, but before it does that, it will dynamically schedule another copy of itself to execute every 5 mins. Once the data becomes available, the repeating task will run once and cancel all future runs.
Is this possible? Am I on the right track?
Any help is much appreciated.
Thanks.

Quartz schedular: how do I setup dynamic job arguments

I'm setting up a Quartz driven job in a Spring. The job needs a single argument which is the id of a database record that it can use to locate the data it needs to process.
The sequence is:
Job starts,
locates next available record id,
processes data.
Because the record id is unknown until the job starts, I cannot set it up when I create the job. I also need to account for restarts if things go bad. From reading Quartz doco it appears that if I store the record Id in the trigger's JobDataMap, then when the server restarts, the job will automatically restart with the same record Id it was original started with.
This is where things get tricky, I'm trying to figure out where and when to get the record Id so I can store it in the trigger's JobDataMap. I'm thinking I need to implement a TriggerListener and use it to set the record Id in the JobDataMap when the triggerFired() callback is called. This will involve a call to the database to get the record Id.
I'm not really sure if this approach is the correct one, or whether I'm barking up the wrong tree. Can someone with some quartz experience tell me if this is correct, or if there is a better way to configure a jobs arguments so that they can be dynamically set and a restart will preserve them?
Thanks
Derek

Quartz org.quartz.jobStore.selectWithLockSQL row lock

I am using Quartz in clustered mode
I have some row lock contention on DB level caused by excessive call to :
org.quartz.jobStore.selectWithLockSQL
"SELECT * FROM QRTZ_LOCKS WHERE SCHED_NAME = :"SYS_B_0" AND LOCK_NAME = :1 FOR UPDATE"
I read quartz docs and is still not very clear to me why is above query is executed.
What is the purpose of having this row lock ?
Regards
The locks table is used by quartz for coordinating multiple schedulers when deployed in cluster mode. In a cluster only one node should fire the trigger, so a lock is used to avoid multiple nodes acquiring the same trigger.
From the clustering section of the documentation (http://quartz-scheduler.org/generated/2.2.1/html/qs-all/#page/Quartz_Scheduler_Documentation_Set%2Fre-cls_cluster_configuration.html%23):
Clustering currently only works with the JDBC-Jobstore (JobStoreTX or
JobStoreCMT), and essentially works by having each node of the cluster
share the same database. Load-balancing occurs automatically, with
each node of the cluster firing jobs as quickly as it can. When a
trigger's firing time occurs, the first node to acquire it (by placing
a lock on it) is the node that will fire it.
In my case, I was experiencing a similar issue. I was using quartz fir running jobs whose logic involved fetching data from a foreign db. Whenever the connection between the application db and foreign db stopped due to some reason and the connection came back up the issue of locks surfaced and we used to get messages like this in the database logs
2021-01-14 12:06:17.935 KST [46836] STATEMENT:
SELECT * FROM HVACQRTZ_LOCKS WHERE SCHED_NAME = 'schedulerFactoryBean' AND LOCK_NAME = $1 FOR UPDATE
2021-01-14 12:06:18.937 KST [46836] ERROR: current transaction is aborted, commands ignored until end of transaction block
To solve this issue I used this property of quartz and once after using this property the issue went away. By default, the foe update part will be there at the end of the query but since the default query is replaced by the query which I wrote in the property file the for update portion is gone and no locks appear now and everything seems to be working smoothly.
selectWithLockSQL: SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ?

Oracle Scheduler - can a single job be both event based and time based

Hi I am new to Oracle Scheduler. My question is - Can we give both repeat interval and event condition in the Schedule object for a single job?
I have this requirement in job scheduling - A job should run at a scheduled time, but only if a certain event has occured.
For eg.
Job1 should run
- at 10 am every day
- but only if same job from yesterday is not running anymore. (This I gonna figure out based on the table entry.) So the event gonna be a cell entry say 'ENDED' in the table job_statuses.
Would be easier if I can give both info in the same job. Else another approach I gonna try is - Schedule the job based on time. If the earlier instance is still running , reschedule the job based on event. But this looks clumsy.
Thanks in advance.
Mayank
I'd encode the condition in the PL/SQL of the procedure itself. i.e. it runs at 10am every day, but the first thing it does is check if the previous job had finished successfully.
What you could do is create 3 jobs
EVENT_JOB
REPEAT_JOB
ACTUAL_WORK_JOB
EVENT_JOB and REPEAT_JOB just start ACTUAL_WORK_JOB. If that is already - or still - running, you get an error on which you can react accordingly.

Resources