php 代码在 cron Laravel 期间意外执行的奇怪问题
Weird issue of php code executing unexpectedly during a cron Laravel
我有以下代码片段,每 5 分钟作为 cron 运行一次。
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
代码如下
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');
}*/
});
现在我遇到的问题
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.
我无法找到为什么即使在只选择 is_complete=0 的情况下,这些条目也会在块中再次被提取的问题。如果这 55 个已经处理过一次,它应该更新为 is_complete=2 并且这个 cron 根据条件不会选择它。
我注意到的一件事是 cron 处理时间超过 5 分钟,因此肯定会发生多次重叠。
但即使重叠,这怎么会发生。
谁能帮我解决这段代码逻辑中的错误。 chunk 应该是这样工作的吗?这里有逻辑错误吗?
使用如下数据库事务:
DB::transaction(function () {
DB::table('fund_transfer_bulk_intermediaries')->update(['is_complete' => 1]);
});
在此处查看更多信息:https://laravel.com/docs/5.7/database#database-transactions
抱歉,我没有足够的声誉 post 发表评论,但是如果您只 运行 一次,代码是否有效?如果是这样,那么重叠似乎是你的问题。
如果是这样,那为什么不阻止重叠而不是试图找出块的问题?
如果您在 app\console\kernel.php 文件中使用调度函数,您至少可以通过使用 withoutOverlapping() 方法来防止重叠并以这种方式解决您的问题。只是一个建议。
另外,顺便说一句,我的代码有一个问题,无论出于何种原因,当我将一系列分页查询链接在一起时,它 永远不会 工作。但是,如果我将它分开并逐行连接查询,它就会起作用。对于我的一生,我无法弄清楚为什么。也许块函数也是如此。
发生这种情况是因为 crons 重叠。在安排 crons 时使用 withoutoverlap 方法。
我有以下代码片段,每 5 分钟作为 cron 运行一次。
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
代码如下
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');
}*/
});
现在我遇到的问题
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.
我无法找到为什么即使在只选择 is_complete=0 的情况下,这些条目也会在块中再次被提取的问题。如果这 55 个已经处理过一次,它应该更新为 is_complete=2 并且这个 cron 根据条件不会选择它。
我注意到的一件事是 cron 处理时间超过 5 分钟,因此肯定会发生多次重叠。
但即使重叠,这怎么会发生。
谁能帮我解决这段代码逻辑中的错误。 chunk 应该是这样工作的吗?这里有逻辑错误吗?
使用如下数据库事务:
DB::transaction(function () {
DB::table('fund_transfer_bulk_intermediaries')->update(['is_complete' => 1]);
});
在此处查看更多信息:https://laravel.com/docs/5.7/database#database-transactions
抱歉,我没有足够的声誉 post 发表评论,但是如果您只 运行 一次,代码是否有效?如果是这样,那么重叠似乎是你的问题。
如果是这样,那为什么不阻止重叠而不是试图找出块的问题?
如果您在 app\console\kernel.php 文件中使用调度函数,您至少可以通过使用 withoutOverlapping() 方法来防止重叠并以这种方式解决您的问题。只是一个建议。
另外,顺便说一句,我的代码有一个问题,无论出于何种原因,当我将一系列分页查询链接在一起时,它 永远不会 工作。但是,如果我将它分开并逐行连接查询,它就会起作用。对于我的一生,我无法弄清楚为什么。也许块函数也是如此。
发生这种情况是因为 crons 重叠。在安排 crons 时使用 withoutoverlap 方法。