Heim >Backend-Entwicklung >PHP-Tutorial >Einführung in atomare Operationen und Dateisperrflock in PHP (Codebeispiel)

Einführung in atomare Operationen und Dateisperrflock in PHP (Codebeispiel)

不言
不言nach vorne
2019-01-28 10:00:482860Durchsuche

Dieser Artikel bietet Ihnen eine Einführung in atomare Operationen und Dateisperren in PHP (Codebeispiele). Ich hoffe, dass er für Sie hilfreich ist.

Atomoperationen von PHP, Dateisperrenherde, Datenbanktransaktionen

PHP erbt nicht die vom POSIX-Standard unterstützte Unix-Sperre, sondern kapselt nur eine Linux-Systemaufrufherde (Semaphor kann auch als verwendet werden). ein Schloss). Es liegt auf der Hand, dass der Verriegelungsmechanismus auch verwendet werden kann, obwohl er weniger effizient ist.
Das PHP-Skript wird im Fastcgi-Container ausgeführt, und Fastcgi ist ein Multiprozesssystem. Wenn das PHP-Programm also auf kritische Ressourcen zugreift, führt dies unweigerlich zu falschen Programmergebnissen.
Es wird geschätzt, dass wir auch das Problem der FastCGI-Container berücksichtigen müssen

Problembeschreibung: Hacker haben Tools verwendet, um unser Backend zu stornieren
Es gibt Rückerstattungen, wenn Hacker gleichzeitig Bestellungen stornieren, was zur Folge hat bei mehreren Rückerstattungen.
Wenn die Anfragen einzeln eingehen, gibt es kein Problem, auch wenn das Intervall 100 Millisekunden beträgt.

Ein PHP-Verarbeitungsprozess ist: Lesen Sie die Rückerstattungsflagge und stellen Sie fest, dass keine vorhanden ist Erstatten, erstatten und dann das Erstattungskennzeichen setzen
Das Problem besteht darin, dass mehrere Anfragen gleichzeitig eingehen und die ausgelesenen Rückerstattungszeichen alle nicht erstattet sind, sodass mehrere Anfragen erstattet werden
Die gleiche PHP-Datei wird mehrfach angefordert Mal zur gleichen Zeit, zur gleichen Zeit

Wir haben es mit PHP File Lock Flock versucht, aber es hat nicht funktioniert, also haben wir die C++-Warteschlange verwendet
Verwendet C++, um einen Port abzuhören, HTTP-Pakete direkt zu empfangen und die Pakete dann im HTTP-Format zurückzugeben, PHP-Programm Ich verwende Curl, um auf mein C-Programm zuzugreifen.
Es entspricht einem Remote-Aufruf und kann es sein zur Verteilung auf anderen Servern bereitgestellt

Oft berücksichtigen wir unsere Parallelitätsfähigkeit von PHP-Code, insbesondere wenn unser PHP-Code eine bestimmte Ressource lesen und schreiben kann. Dies bedeutet jedoch nicht, dass alle Operationen in PHP atomar, transaktional und parallelisierbar sind. Da das PHP-Skript in einem Fastcgi-Container ausgeführt wird und Fastcgi mehrere Prozesse durchführt, führt der Zugriff des PHP-Programms auf kritische Ressourcen unweigerlich zu falschen Programmergebnissen.

Die Lösung des Problems besteht darin, einen Verriegelungsmechanismus zu verwenden. PHP erbt nicht die vom POSIX-Standard unterstützten Unix-Sperren wie Datensatzsperren fcntl, Thread-Sperren usw., sondern kapselt nur einen Linux-Systemaufruf-Flock (Semaphoren können auch als Sperren verwendet werden), und die Flock-Form ist flock( $fp,$type), wobei $fp das Dateihandle ist und $type ist:
/* Wenn eine Datei zum Lesen und Schreiben geöffnet wird, ist es normalerweise erforderlich, der Datei */

1. Gemeinsame Sperre LOCK_SH:

Normalerweise ist eine gemeinsame Sperre erforderlich, wenn ein Prozess einen Lesevorgang aus einer Datei anfordert. Gemeinsame Sperren können Lesevorgänge zwischen beliebigen Prozessen unterstützen. Wenn Sie eine Datei mit einer gemeinsamen Sperre schreiben, wird der Prozess blockiert und in den Ruhezustand versetzt, bis die gemeinsame Sperre aufgehoben wird:
normalerweise ein Prozess Fügen Sie dem Schreibvorgang der Datei eine exklusive Sperre hinzu. Sobald die Datei gesperrt ist, wird jeder andere Prozess beim Zugriff auf die Datei blockiert, bis sie entsperrt wird.

3. LOCK_UN Entsperren:
Entsperren Sie das gesperrte Dateihandle

Diese Sperrmethode kann zwar die Atomizität des gesperrten Programmblocks sicherstellen, beeinträchtigt jedoch auch die Effizienz des Programms Daher sollte in unserem eigentlichen Programm so wenig Programmlogik wie möglich (insbesondere exklusive Sperren) zwischen den Sperr- und Entsperrcodes des Programms eingebettet werden, um sicherzustellen, dass das Programm so schnell wie möglich entsperrt wird.

Schließlich hängen Sie das Programm nach dem Sperrmechanismus an:

<?php 
$usrinfo = isset($_GET["usrinfo"])?$_GET["usrinfo"]:exit(1); 
$stinfo = isset($_GET["stinfo"])?$_GET["stinfo"]:exit(1); 
echo $stinfo; 
$pid = posix_getpid(); 
$fp = fopen(“usrinfo.txt”,”a+”); 
$num = rand(0,100000); 
flock($fp,LOCK_EX); 
fwrite($fp,”user:”.$usrinfo.” stinfo:”.$stinfo.”–”.$pid.”–”.$num.”\n”); 
fwrite($fp,”talking 1 — pid:$pid and num:$num\n”); 
flock($fp,LOCK_UN); 
fclose($fp);

Die Ausführung dieses Programms unter normalen Umständen führt zu korrekten Ergebnissen.

Welche Methode kann verwendet werden, um die Atomizität bei Batch-Operationen sicherzustellen?

Zum Beispiel: Mehrere Artikel löschen, aber einer davon wurde gelöscht. Wenn hier ein Fehler auftritt, wie können Sie den gesamten Vorgang rückgängig machen und die Fehlermeldung finden?

Datenbanktransaktionen garantieren Atomizität, können aber keine Fehlermeldungen finden. Aber was sollen wir tun, wenn wir auf ein Szenario stoßen, in dem Transaktionen nicht verwendet werden können?


Es ist am sinnvollsten, Datenbanktransaktionen zu verwenden. Wenn ein Vorgang fehlschlägt, wird ein Fehler ausgegeben.
Wenden Sie Logik an, um sicherzustellen, dass jeder Vorgang aufgezeichnet wird, ob Erfolg oder Misserfolg aufgezeichnet werden. Wenn zwischendurch etwas schief geht, können Sie den Erfolg rückgängig machen. Im Allgemeinen handelt es sich bei unserer Löschung um eine gefälschte Löschung, daher ist sie sehr einfach. Wenn es gelöscht wird, müssen bei der Aufzeichnung vollständige Informationen erfasst werden.

PHP verwendet eine Dateisperre, um eine Prozesssperre zu simulieren und eine atomare Operation zu realisieren.
Verwenden Sie PHP, um eine atomare Operation zu realisieren, aber PHP selbst bietet keinen Prozesssperrmechanismus. Verwenden Sie den PHP-Dateisperrmechanismus, um eine Prozesssperre durch eine Datei zu simulieren Sperre, um den atomaren Betrieb zu realisieren.

Verwenden Sie vor dem Code für die atomare Operation eine exklusive Sperre, um eine Datei zu öffnen. Der Code lautet wie folgt:

$fp = fopen( LOCK_FILE_PATH, "r" );
if (!$fp) {
 echo "Failed to open the lock file!"; 
 exit(1);//异常处理
 }
flock ( $fp, LOCK_EX );

Entsperren Sie nach dem Code für die atomare Operation die Datei und schließen Sie die Datei Der Code lautet wie folgt:

flock ( $fp, LOCK_UN );
fclose ( $fp );

Der gesamte Pseudocode lautet:

define("LOCK_FILE_PATH", "/tmp/lock");
if( !file_exists(LOCK_FILE_PATH) ){ 
$fp = fopen( LOCK_FILE_PATH, "w" );
fclose ( $fp );
}
$fp = fopen( LOCK_FILE_PATH, "r" );
if (!$fp) {
echo "Failed to open the lock file!";
exit(1);//异常处理
}
flock ( $fp, LOCK_EX );
//此处添加原子操作代码
flock ( $fp, LOCK_UN );
fclose ( $fp );

Das Obige kann atomare PHP-Operationen implementieren und Konflikte vermeiden.

atomare PHP-Operationen und atomare MySQL-Operationen

Die übliche Methode für atomare Operationen ist die Implementierung eines Daten-Rollbacks. Es ist ganz einfach, PHP zum Implementieren einer Datenbank-Rollback-Operation zu verwenden:
1, Datenbankverbindung herstellen
2, mysql_query('BEGIN');
3, $SQL = "...";
mysql_query($SQL); Führen Sie entsprechende Datenbankoperationen aus
4, bestimmen Sie die Rollback-Bedingungen:
if(mysql_errno)
{
print mysql_error();
mysql_query('ROLLBACK'); Rollback, wenn ein Fehler auftritt
exit(}
5, Sie können die obigen Schritte 3 und 4 wiederholen, um den Vorgang zu starten (Andere Vorgänge können in der Mitte hinzugefügt werden, nicht nur Datenbankaktualisierungen. Achten Sie jedoch darauf, dass eine Transaktion nicht zu lange dauert, da dadurch alle von Ihnen verwendeten Tabellen gesperrt werden, was sich auf die Verwendung anderer Programme auswirkt.)
Sie können dies auch in mehreren Schritten tun. Schreiben Sie nach einer korrekten SQL-Update-Anweisung absichtlich eine falsche, um zu sehen, ob sie zurückgesetzt wird.
6, beenden Sie den Rollback-Vorgang
mysql_query('COMMIT'); Wenn Sie hierher gelangen können, sind alle oben genannten Datenbankvorgänge korrekt und werden offiziell zur Ausführung eingereicht

Dies ist der gesamte Prozess Bei der Verwendung von PHP zur Implementierung atomarer Operationen muss besonderes Augenmerk auf die Einrichtung einer Tabellenstruktur gelegt werden, die Daten-Rollback-Operationen unterstützt.

Darüber hinaus gibt es neben dem Festschreiben noch andere Möglichkeiten, die Rollback-Operation zu beenden.


Das obige ist der detaillierte Inhalt vonEinführung in atomare Operationen und Dateisperrflock in PHP (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen