2017-05-28 91 views
0

我正在製作一個腳本,每次請求/運行此腳本時都會獲取MySQL MyISAM表的數據。 查詢是這樣的:計數器避免重複使用多線程請求

SELECT * FROM table LIMIT $ offset,10;

的問題是,在$偏移必須在第一請求中0和10秒,20在第三等等等等 然後創建一個新的表,其中我有$一個偏移計數器每次該增量10請求腳本 。

您必須知道該腳本會同時有很多請求。請求不是用戶(訪問) 請求是我的軟件在超過5臺PC上運行,並且這些軟件中的每一個都使用 以上超過1000個線程處理對此腳本的請求。然後,如果有2個或更多的線程在同一時間向這個腳本請求,那麼我搜索一個解決方案不會返回 到這些線程相同的結果。 另外我需要這個計數器會增加完美。

function GetAndUpdateCounter($numberToAdd) 
{ 
    $link = mysql_connect('localhost','root','abcd1234'); 
    if(!$link) die ('Could not connect to database: '.mysql_error()); 

    mysql_select_db('dbcounter',$link); 

     // in the 2 lines below I have my question about what happend if 2 or 
     // more threads/request do this at same time, will get same result and will do same update 
     $result = mysql_query("SELECT id FROM counter"); 
    mysql_query("UPDATE counter SET id=(id+$numberToAdd);"); 

    $row = mysql_fetch_array($result, MYSQL_ASSOC); 
    mysql_close($link); 
    return $row['id']; 
} 

示例調用函數

$offset = GetAndUpdateCounter(10); 

$ Q =請求mysql_query( 「SELECT * FROM表LIMIT $偏移,10」);

回答

0

在列出你的問題的解決方案之前,我想給你一個建議:不要,請不要使用mysql_函數,它們在最新的PHP版本中可能有害並且不推薦使用。

有幾種方法可以實現你想要的。我會按優先級從小到大的順序列出它們。

  1. 手動MySQL表鎖。您可以鎖定一個表格,選擇+更新所需的值,然後再次解鎖表格。我在優先列表中首先選擇它的原因是,它有一個高效的內部鎖定系統。原型,從MySQL手冊頁採取:

    LOCK TABLES trans READ, customer WRITE; 
    SELECT SUM(value) FROM trans WHERE customer_id=some_id; 
    UPDATE customer 
        SET total_value=sum_from_previous_statement 
        WHERE customer_id=some_id; 
    UNLOCK TABLES; 
    
  2. 在你的腳本語言(PHP)使用相同的鎖定原理。您可以選擇和更新字段的全部過程,僅爲鎖定目的創建一個空文件,或者您可以使用Memcached進行設置,檢查進程是否繁忙,並在進程完成時釋放。這些方法是不建議,因爲其中一個進程在處於「繁忙」模式時可能總是崩潰,從而阻塞其他進程,直到Memcached發佈。