2

昨天在写脚本的时候,发现了一个问题,当我去分块去处理数据的时候,数据表的数据总是会出现缺失处理的情况。 在这里写个笔记 记录下这次的踩坑过程。 网上有好多地方能看到这个坑,但是都没有给出具体的解决方案。

Laravel中chunk方法分块处理数据的坑: Laravel中chunk方法分块处理数据

先说会引发这个问题的原因: 主要是因为数据表的查询与更新的where字段自同一张表,那么我们在更新数据的时候,就会因为chunk的分块机制,导致查询的数据是不全的。

这是chunk的分块机制源码:

public function chunk($count, callable $callback)
{
    // 我理解的是类似于limit,offset 实现数据分页查询  
    $results = $this->forPage($page = 1, $count)->get();

    while (count($results) > 0) {
        // On each chunk result set, we will pass them to the callback and then let the
        // developer take care of everything within the callback, which allows us to
        // keep the memory low for spinning through large result sets for working.
        // 如果用户回调中,更新的字段与查询的字段是一个条件,就会出现这样的问题             
        if (call_user_func($callback, $results) === false) {
            return false;
        }

        $page++;

        $results = $this->forPage($page, $count)->get();
    }

    return true;
}

那么如何解决这种问题呢? 我是这么处理的:

public function handle()
{
    // 1.先去查询需要更新的数据量 
    $count = DB::table('table')
               ->where('status', '=', 0)
               ->count();
    echo "需要推送的数量:$count\r\n";
    while ($count) {
        // 2.然后limit去查数据 
        $data= DB::table(self::OPEN_API_WUBA_TEST_CLUE)
                 ->where('is_push', '=', self::IS_PUSH_FAILED)
                 ->limit(100)
                 ->get();
        ! empty($data) && $this->processData($data);
        // 3.批次处理完数据,再去查询下 需要更新的数据,直到更新完毕退出循环  
        $count = DB::table('table')
                   ->where('status', '=', 0)
                   ->count();
        echo "剩余推送的记录数:$count\r\n";
    }
    exit("数据全部推送完毕.\r\n");

}

private function processData($data)
{
    // TODO(xiaoyi):处理数据业务逻辑
}



萧逸
709 声望29 粉丝

致力于分享效率工具、有趣好玩的开源项目、技术干货。关注我,带你发现新大陆~