1

I want to import products using cronjob. But issue is that when import job runs twice at the same time. How can I protect from these? I try to do this:

private function isImportAlreadyRunning()
{
    $isRunning = false;
    $cronSchecduleCollection = Mage::getModel('cron/schedule')->getCollection()
        ->addFieldToSelect(array('job_code', 'status'))
        ->addFieldToFilter('job_code', array('eq' => 'my_import_products'))
        ->addFieldToFilter('status', array('eq' => 'pending'))
        ->addFieldToFilter('executed_at', array('neq' => 'NULL'))
        ->load();

    Mage::log('Cron size: ' .$cronSchecduleCollection->getSize());
    if($cronSchecduleCollection->getSize() > 1) 
    {
        $isRunning = true;
    }

    return $isRunning;
}

But these doesn't work because $cronSchecduleCollection->getSize() is equals 1, even if I run 2 process simultaneously. Class is singleton because it belongs to Helper.

Milos
  • 647
  • 6
  • 21

1 Answers1

0

You need to "lock" the database. I use that kind of functions :

private function _takeLock() {
    $result = false;
    $st = $this->_dbCntr->query('select is_free_lock("BMS_PRODUCT_IMPORT");');
    if ($st->fetchColumn() == 1){
        $st2 = $this->_dbCntr->query('select get_lock("BMS_PRODUCT_IMPORT", 0);');
        $result = $st2->fetchColumn() == 1;
    }
    return $result;
}

private function _releaseLock() {
    $this->_dbCntr->query('select release_lock("BMS_PRODUCT_IMPORT");');
}

And then:

        $this->_dbCntr = Mage::getSingleton('core/resource')->getConnection('core_write');

        // Take a lock
        if (!$this->_takeLock()) {
            return 'Process already running. Aborting';
        }
  process of import

        $this->_releaseLock();
Christophe Ferreboeuf
  • 1,048
  • 14
  • 26
  • Txn for answer, but what if cronjob stops and never release table - in case when import takes too long? – Milos Sep 11 '14 at 10:47
  • sorry for the delay, I was on holidays but the lock is released with release_lock or when the connexion is closed. The connexion is active while the script is running that means that if the script dies or is killed, the connexion is closed and the lock released. Hope it helps. If the import is long, then better to not start a new one for the consistency of data. If you question is "is the db locked for everything?", the answer is no, only for the "lock" that has this name. – Christophe Ferreboeuf Sep 23 '14 at 12:48
  • Tnx for reply, but i resolve this issue using file to lock: http://stackoverflow.com/questions/10552016/how-to-prevent-the-cron-job-execution-if-it-is-already-running?lq=1 – Milos Sep 23 '14 at 13:24
  • this can be tricky with load balancer but not every webstore needs a load balancer so it is a nice one as well :) – Christophe Ferreboeuf Sep 23 '14 at 13:41