Question

My database table contains scheduled jobs with the time at which they will start. Currently I have a continuous thread running that keeps checking if there is job scheduled for this moment. The method gives no exception no errors but the job never runs. According to what I think,I am checking the table for the time entry in an improper fashion and it misses by a second or seconds.

This is what I am doing :

SELECT job FROM mytable where time = new java.sql.Time(new GregorianCalendar().getTimeInMillis())

The above SQL is inside a continuous thread keeps on running.

Is this the correct way for matching the time entries ?

Was it helpful?

Solution

Having to poll the database continually is needlessly inefficient. You're much better off querying the database for the start time of the earliest job, and then setting a timer to wake up when it's time to run that job. For example:

select top(1) * from  myTable where time <= current_time  // however you get the current time
    order by time

Then, subtract the current time from the job start time. You can then set a timer to wait that amount of time. When the timer fires, start the job and query the database for the next job.

Obviously if the start time is before the current time, you'll want to start the job immediately and then check the database for the next job.

But then there's the problem of how to handle new jobs that come in while you're waiting for the first job to start. Or if there are no jobs in the database and a new job comes in. In either case, the best solution is to somehow be notified that a new job has come in so that you can query the database. Then, if the new job's start time is before the current job you're waiting on, you destroy the existing timer, set a new timer to wait for the new, earlier, job, and go back to waiting.

This setup completely eliminates periodic polling of the database. You depend instead on notification when a new job arrives. Without more information about your program's structure I can't say specifically how you'd code it, or even if it's possible in your situation. But if you have control over the design of the system, I would strongly recommend that you do it this way.

OTHER TIPS

Your current approach is not good, it is brittle and relies on the thread being active at all times. You should not try to match a time exactly for a scheduler, but instead, check if the time is now past (whether past by 1millisec or 1 minute doesn't matter, you just need to start the job).

What if your scheduler thread only runs once every 1 minute and your times are in second granularity?

Instead, compare for less-than or greater-than, not equality, and add flag for status or another timestamp to track when the job actually did start.

Something like:

 select * from jobs where scheduledStartTime < SYSDATE and actualStartTime == null

That way you dont have to match it exactly, you just know it needs to start because the time is past.

Note: Your StartJob logic needs to update actualStartTime with a value to make it non-null.

PS: If you really do want dates to match in a database, but don't need high resolution scheduling, then avoid storing full granularity, and truncate the values that you store. In Oracle, for example, I would use TRUNC(dt, 'MI') on the date to store dates with even minute values. Those are simpler to match. Still, there is usually no reason to match the date exactly in a scheduler, instead, you match using range logic.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top