2017-05-28 7 views
0

Ich mache ein Skript, das Daten von einer Mysql MyISAM-Tabelle jedes Mal, dass dieses Skript angefordert/ausgeführt wird. Die Abfrage lautet etwa so:Counter vermeiden Wiederholung mit Multithread-Anfragen

SELECT * FROM Tabelle LIMIT $ offset, 10;

Das Problem ist, dass der $ offset 0 in der ersten Anfrage und 10 in der zweiten, 20 in der dritten usw. sein muss. Dann habe ich eine neue Tabelle erstellt, wo ich einen Zähler für $ offset, die jedes Mal +10 inkrementieren Das Skript ist angefordert.

Sie müssen wissen, dass das Skript zur selben Zeit viele Anfragen haben wird. die Anfrage sind nicht Benutzer (Besuche) die Anfrage sind meine Software läuft in mehr als 5 PC und jede dieser Software läuft mit mehr als 1000 Threads Anfragen an dieses Skript. Dann suche ich eine Lösung für nicht zurück zu diesen Threads die gleichen Ergebnisse, wenn 2 oder mehr Threads genau dieses Skript gleichzeitig anfordern. Auch ich brauche diesen Zähler wird perfekt inkrementieren.

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']; 
} 

Beispiel Aufruf der Funktion

$offset = GetAndUpdateCounter(10); 

$ q = mysql_query ("SELECT * FROM Tabellen LIMIT $ offset, 10");

Antwort

0

Bevor Sie die Lösungen für Ihr Problem auflisten, möchte ich Ihnen einen Rat geben: Verwenden Sie bitte keine mysql_ Funktionen, sie sind potenziell schädlich und in der neuesten PHP Version veraltet.

Es gibt mehrere Möglichkeiten, wie Sie erreichen können, was Sie wollen. Ich würde sie in aufsteigender Reihenfolge nach Priorität auflisten.

  1. Manuelle MySQL Tabellensperren. Sie können eine Tabelle sperren, + Ihren gewünschten Wert aktualisieren und dann die Tabelle wieder entsperren. Der Grund, warum ich es zuerst in der Prioritätenliste wählte, ist, dass es ein gutes internes Verschlusssystem mit hoher Effizienz hat. Prototyp von MySQL Hand Seiten genommen:

    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. Unter Verwendung des gleichen Verriegelungsprinzip in der Skriptsprache (PHP). Sie können entweder flock den gesamten Vorgang des Auswählens und Aktualisierens des Felds mit dem Erstellen einer leeren Datei nur zum Sperren Zweck, oder Sie können Memcached verwenden, um zu überprüfen, ob der Prozess beschäftigt ist, und freigeben, wenn der Prozess abgeschlossen ist. Diese Ansätze sind nicht empfohlen, da einer der Prozesse immer abstürzen könnte, während er sich in einem "busy" -Modus befindet, wodurch die anderen Prozesse blockiert werden, bis Memcached freigegeben wird.