问题代码如下:

\DB::table('records')->where('status','=', 1)->chunk(50, function ($records) {
    if (empty($records)) {
        return;
    }
    //执行更新
    $records->each(function ($item, $key) {
        \DB::table('records')->where('id','=', $item['id'])->update(['status' => 2]);
    });
});

问题分析

chunk方法解析的SQL形如:
SELECT * FROM records WHERE status = 1 OFFEST = {$offset} LIMIT {$limit}

以上代码解析的语句:

SELECT * FROM records WHERE status = 1 OFFEST = 0 LIMIT 50;
SELECT * FROM records WHERE status = 1 OFFEST = 50 LIMIT 50;
····
SELECT * FROM records WHERE status = 1 OFFEST = 50*n LIMIT 50;

如果查询条件一直在变化会导致OFFSET位移发生变化,导致错漏部分查询结果。

解决办法

$limit = 50;
while (true) {
    $records = \DB::table('records')->where('status','=', 1)->limit(50)->get();
    //执行更新
    $records->each(function ($item, $key) {
          \DB::table('records')->where('id','=', $item['id'])->update(['status' => 2]);
    });

    if(empty($records) || count($records) < $limit){
        break;
    }
}

总结

chunck 方法适用于记录查询场景,在更新记录是慎用

相关文章:

  • 2022-03-08
  • 2021-11-27
  • 2022-12-23
  • 2021-09-05
  • 2022-12-23
  • 2022-01-29
  • 2021-08-08
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-10-11
  • 2021-11-05
  • 2022-12-23
  • 2022-03-07
  • 2021-08-25
相关资源
相似解决方案