【问题标题】:Script restarts executing after a while脚本在一段时间后重新开始执行
【发布时间】:2011-04-04 06:16:05
【问题描述】:

我正忙于 cakePHP 的一个项目,我需要解析几个 XML 文件并将相关数据插入到我的 mysql 数据库中。脚本插入了它应该插入的内容,这不是问题。例如,如果我解析一两个文件(大约 7000-8000 条记录),就不会出错。

当我解析第三个或第四个 xml 文件时,问题就开始了。插入记录一分钟后,我看到数据库中成功插入了 9000-10000 条记录,但突然间脚本似乎重新启动。我注意到表中存在 0 条记录,它重新开始插入所有记录。所以脚本只需要很长时间才能执行。

短sn-p:

$content = simplexml_load_file($file);

/**
 * Process line per line 
 */              
foreach ($content->product as $line) {              
  // create new record in products database table
  $product = array();
  $product['Product']['productid'] = $line->attributes()->sku_number;
  $product['Product']['name'] = $line->attributes()->name;
  $product['Product']['description'] = empty($line->description->long) ? $line->description->short : $line->description->long;
  $product['Product']['link'] =  $line->URL->product;
  $product['Product']['affiliate'] = 'linkshare';
  $product['Product']['price'] = $line->price->retail;
  $product['Product']['brand'] = strtolower($line->brand);
  $product['Product']['image'] = $line->URL->productImage;

  // if not in rejectedproducts, save the new product to the database
  if (!$rejectedproductModel->findByProductid($product['Product']['productid'])) {
  $productModel->create();
  $productModel->save($product);        
}

有人有这方面的经验吗?可能是什么原因以及更多可能的解决方案:)

谢谢

【问题讨论】:

  • 你是如何传递文件的?那么在添加文件 1 和 2 时,您是否在添加文件 3 和 4 时重新添加它们?还是一次性添加文件 1、2、3 和 4?

标签: php mysql cakephp bulkinsert


【解决方案1】:

我将展示一些代码。提要的调用是这样发生的 parseDirectory 方法检查指定文件夹中的所有 xml,并通过调用 linkshare 操作并传递文件名来解析它们。

function index() {
        set_time_limit(0);

        #$this->updateFeeds();

        App::import('Model', 'Product');        
        $productModel = new Product();      
        # truncate table products before adding new records to avoid duplicate records
        $productModel->query('TRUNCATE TABLE products');

        # parse all files from shareasale
        #$this->__parsedirectory('feeds/shareasale');   
        # parse all files from linkshare
        $this->__parsedirectory('feeds/linkshare'); 

        # send mails where necessary
        $this->redirect(array('controller' => 'subscriptions', 'action' => 'sendmails'));
    }

私有函数

function __parsedirectory($dir) {   
    # retrieve name affiliate out of directory
    $affiliate = explode('/', $dir);
    $affiliate = $affiliate[1];     

    $dh = opendir($dir);
    while (($file = readdir($dh)) !== false) {
        if ($file != '.' && $file != '..' && !$this->__endswith($file, 'gz')) {
            $this->requestAction('/parse/' . $affiliate . '/file:' . $file);
            $this->Session->setFlash($affiliate . '/' . $file . ' parsed');
        }
    }
    closedir($dh);
    $this->autoRender = false;
}

【讨论】:

  • 你应该编辑你的问题,而不是下次添加答案
【解决方案2】:

我认为问题出在这段代码上:

  # truncate table products before adding new records to avoid duplicate records
        $productModel->query('TRUNCATE TABLE products');

这是避免重复记录的糟糕方法。这应该通过对数据库的限制来管理。话虽如此,不知何故,这段代码在进程中间再次运行。

这是设置为 CRON 还是以某种方式自动运行?如果是这样,那么当下一个文件开始时,前一个文件还没有完成解析。

【讨论】:

  • 我并没有真正执行 TRUNCATE 来避免重复记录;)在产品表中,我只想成为 XML 提要中当前存在的产品。所以我需要完全清空它,这样它们就不会是任何旧记录;)这段代码应该被执行。事实上,它似乎运行了好几次。问题是为什么 :) 现在我自动运行它,但目标是在投入生产时在 CRON 作业中执行它。我注意到当我在本地主机上执行相同的脚本时一切顺利。也许是内存问题?
  • 我刚刚注意到这是function index(),你是在浏览器中运行它吗?如果是这样,您应该考虑在命令行运行它。我敢打赌命令行不会有同样的问题。可能是在一定时间后,浏览器会尝试重新加载页面。
  • 我在浏览器中运行它是的 :) 我会试一试,虽然我猜这个问题会持续存在,因为当我在 localhost 上运行它时它做得很好。谢谢
  • 我已经将 cakePHP 项目从共享托管服务器转移到另一个更强大的专用服务器,现在它运行顺利 :) 所有记录都按原样插入,脚本不会自行重启.即使我在浏览器中运行它。所以这只是一个内存问题。
猜你喜欢
  • 2018-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多