2012-03-18 77 views
3

我有一個WordPress插件和一個按計劃執行的備份腳本。值得注意的是,如果有人連續多次訪問該頁面,它可以多次執行備份腳本。有關如何防止多次執行的任何想法?如何防止PHP多次執行代碼?

global $bwpsoptions; 

     if (get_transient('bit51_bwps_backup') === false) { 

      set_transient('bit51_bwps_backup', '1', 300); 

      if ($bwpsoptions['backup_enabled'] == 1) { 

       $nextbackup = $bwpsoptions['backup_next']; //get next schedule 
       $lastbackup = $bwpsoptions['backup_last']; //get last backup 

       switch ($bwpsoptions['backup_interval']) { //schedule backup at appropriate time 
        case '0': 
         $next = 60 * 60 * $bwpsoptions['backup_time']; 
         break; 
        case '1': 
         $next = 60 * 60 * 24 * $bwpsoptions['backup_time']; 
         break; 
        case '2': 
         $next = 60 * 60 * 24 * 7 * $bwpsoptions['backup_time']; 
         break; 
       } 

       if (($lastbackup == '' || $nextbackup < time()) && get_transient('bit51_bwps_backup') === false) { 

        $bwpsoptions['backup_last'] = time(); 

        if ($lastbackup == '') { 

         $bwpsoptions['backup_next'] = (time() + $next); 

        } else { 

         $bwpsoptions['backup_next'] = ($lastbackup + $next); 

        } 


        update_option($this->primarysettings, $bwpsoptions); 

        $this->execute_backup(); //execute backup 

       } 

      } 

     } 
+3

在數據庫中設置一個表示時間的字段並進行計算,以便如果上次運行腳本和當前時間之間的差值大於't',則不要運行腳本。 – 2012-03-18 18:05:40

+0

你在哪裏填充'$ bwpsoptions'?如果它不是來自外部來源,如數據庫,文件,會話等,那麼它將在下一頁加載時被遺忘。 – 2012-03-18 18:08:48

回答

1

將最近的備份日期/時間存儲在服務器上的某個外部文件或數據庫中,並使用對該值的檢查!

+0

試過了。在繁忙的網站上,文件鎖定機制不夠快... – 2012-03-18 18:09:14

+0

爲什麼不在單獨的頁面上備份此備份腳本?只要條件滿足,就打電話開始/包含頁面! – hjpotter92 2012-03-18 18:12:11

+1

@ChrisWiegman,** A **是「服務器上的外部文件或*到數據庫*中」。如果在D/B中使用batchQ行/表,則不會出現此問題。只需更新time = requested_time的備份時間戳記行上的時間即可。如果此更新執行的受影響行數爲1,那麼此過程會執行備份,否則其他進程會將其剔除。 – TerryE 2012-03-18 18:43:29

2
  • 在代碼的開頭創建一個文件。
  • 代碼運行完畢後刪除文件。
  • 在代碼的開頭,確保該文件在運行之前不存在。

有點像Linux中的apt-get鎖定。

+0

我已經嘗試過了,但它在繁忙的網站上速度不夠快。 – 2012-03-18 18:09:38

+0

這個腳本被請求的速度有多快? – 2012-03-18 18:17:29

0

我假設這個備份在某處做了備份。

因此,檢查最新備份的元數據,如果創建時間不夠遠,請不要執行備份。

我認爲這不是一個cron工作有一個很好的理由?

+0

是的,這不是一個cron工作,因爲太多的人不能處理它。我必須在實際的cron作業不可用並且wp-cron不夠靈活的環境中使用它。 – 2012-03-18 18:12:51

3

如果您的網站非常繁忙,並且基本的鎖定機制無法正常工作(我個人無法想象,但是哦!),您可以嘗試PHP會話的垃圾回收器的解決方案。

只需隨機選擇一個介於0和10之間的數字,如果數字爲0,請執行備份。如果現在有10個用戶幾乎同時調用您的備份腳本,統計上只有一個用戶會真正執行備份。

define("BACKUP_PROBABILITY", 10); 
if (mt_rand(0, BACKUP_PROBABILITY) == 0) 
    doBackup(); 

如果您的網站非常頻繁地出現,您可以增加最大值(10)。

如果在這10次訪問中沒有得到0,則接下來的10個訪問者將獲得他們的機會。

您當然需要某種鎖定機制,並且仍然有可能(儘管不可信)您最終將擁有多個甚至10個備份。

我發現這個關於互斥鎖(鎖)在PHP中的問題。可能有幫助:PHP mutual exclusion (mutex)