Situation: I created a cron job. It was to add orders entered by customers to an API. I set it to run after every one minute.
Problem: Sometimes, when there were too many pending orders, second cron job was being called before first one gets ended. It was resulting in duplicate orders sent through API.
Solution: I created a table named as cron_jobs in my database. It has two columns, ID and status. When a cron job runs, it checks whether the status is 0 or not. If status is 0, it updates the status as 1. It completes its process and marks the status again as 0. If the status of a job is 1 (it means it is already running), and it is hit again, the operation is terminated.
Unexpected Trouble: This solution seems logically correct. But when I implemented it, the results were shocking. When a job is run, its status is updated. But when it is invoked again, database still returns status 0 and it keeps on executing. I have also used sleep method so that I have enough time to investigate the issue. But the database always returns incorrect value than what I can see using phpmyadmin.
Please do no think that I might have committed some stupid mistakes. Second instance of a file is always fetching incorrect value before the first instance is completely invoked. Have a look at my code:
<?php
$Output = mysql_fetch_assoc(mysql_query("select status from jobs where ID='1'"));
if($Output['status'] == '0')
{
mysql_fetch_assoc(mysql_query("update jobs set status='1' where ID = '1'"));
mysql_fetch_assoc(mysql_query("update jobs set invoked = invoked+1 where ID = '1'"));
echo 'Executed';
}
else
{
echo 'Error: Another cron job already in process. Operation terminated!';
die();
}
/*I perform some lengthy tasks here*/
/*Sleep function called to check whether another instance of the program works while this one is in progress */
sleep(60);
/*Task is complete. We are marking 0 as status so that another instance is allowed to work on.*/
mysql_fetch_assoc(mysql_query("update jobs set status='0' where ID = '1'"));
?>
Observation 1: It works perfectly if I run the second instance in another browser or another computer.
Observation 2: I tried to investigate whether it is ACTUALLY being called several times or not. I made another column in the table as "No_Of_Times_Invoked". And I found that the code actually failed when I used from the same browser.