Search code examples
phplaravelcronrace-condition

Weird issue of php code executing unexpectedly during a cron Laravel


I have the following code snippet which runs as a cron every 5 minute.

The summary of the code is

1. Picks up 80 rows where the status is is_complete=0 for processing
2. Does some processing on the data format in a foreach loop, and is bulk updated as is_complete=2 in the table as a bulk update at the end on the foreach
3. After bulk update, another loop starts which process transaction for each of 80 entries one by one

The code is below

DB::table('fund_transfer_bulk_intermediaries')->orderBy('fund_transfer_bulk_intermediaries_id')->where([['read_status','=', 'success'],['is_complete', '=', 0]])->chunk(80,function($fund_transfer_bulk_intermediaries) use ($updated_date) {

                //Picks up all 80 entries with is_complete flag 0

                foreach ($fund_transfer_bulk_intermediaries as $fund_transfer_bulk) {

                    //Does some processing on 80 entries



                }
            //Update the entries of 80 rows as "is_complete=2" so that it wont be picked up again for processing


                foreach ($fund_transfer_bulk_intermediaries as $fund_transfer_bulk) {

                    //Looped through each of 80 entires for processing 80 transactions one by one
                }
//After completion of 80 transaction processing, status is updated to 1 (successfully processed all transaction)
                /*if(sizeof($ftdataupdate) > 0) {
                    $this->fund_transfer_bulk_intermediary_repository->bulkUpdate($ftdataupdate, 'is_complete');
                }*/
            });

Now the problem which I faced

1. There were around 800 rows which had to be picked up for processing as 80 chunks.

2. A cron is running every 5 minute which runs the above code and processes 80 rows at a time and the processes in the code happens.

3. Some 55 entries have run thrice and transactions happened thrice instead of one.

4. Ideally, since is_complete is updated to 2 (after its picked up once by the cron), this cron shouldn't pick up those rows in table again for processing. Though it had took same row that too three times. 

I am unable to find the issue why those entries was picked up again in the chunk even when the condition was there whcih picks only is_complete=0. If those 55 have processed once, it should have updated as is_complete=2 and this cron as per the condition wouldnt pick it up.

One thing I noticed was the cron took more than 5 minute to process, so multiple overlaps happened for sure.

But even in case if overlap how did this happen.

Can someone help me out with whats wrong in this code logic. Is chunk suppose to work like this? Is there any logical error here ?


Solution

  • This is happening because the crons are overlapping. Use withoutoverlap method while scheduling the crons.