1. Melden Sie einen Fehler: "Die PDO -Instanz kann nicht in der Transaktion tauschen."
Durch Abfragen des Laravel -Source -Code können Sie bestätigen, dass die Ausnahme in setPdo -Methode ausgelöst wird:
<? Phppublic Function setpdo ($ pdo) {if ($ this-> Transactions> = 1) {neue runTimeexception werfen ("kann die PDO-Instanz nicht während der Transaktion tauschen."); } $ this-> pdo = $ pdo; Gibt $ this;}?> Im wahrsten Sinne des Wortes tritt dieser Fehler auf, da die Datenbankverbindung beim Einschalten der Transaktion umgeschaltet wird. Manchmal kann dieser Fehler jedoch auch dann auftreten, wenn der Code die Datenbankverbindungen nicht explizit wechselt. Wenn beispielsweise bei der Ausführung einer Abfrageanweisung ein Fehler auftritt, verwendet das System die tryAgainIfCausedByLostConnection -Methode, um festzustellen, ob das Problem durch eine verlorene Verbindung verursacht wird. In diesem Fall verbindet das System durch die reconnect der Methode. Bei der Wiederverbindung führt das System eine Reinigung durch die disconnect durch, und setPdo -Methode wird aufgerufen.
Nach der Klärung der Ursachen und Konsequenzen wissen Sie natürlich, wie Sie das Problem lösen können: Überprüfen Sie die Netzwerksituation und bestätigen Sie die Ursache des Datenbankverbindungsverlusts. Dies kann daran liegen, dass es ein Problem mit einem bestimmten Gerät gibt oder es an unsachgemäßen timeout zurückzuführen ist. Eine relativ dirty Methode besteht darin, DB::reconnect() auszuführen, bevor Sie die Datenbank abfragen und wieder anschließen.
2. Fehler: "Job kann nicht löschen: Not_found"
Dieses Problem hat eigentlich nichts mit Laravel zu tun, sondern wird durch den Warteschlangenservice -Beantalk verursacht.
Beanstalk
Um dieses Problem zu lösen, müssen Sie zunächst den Lebenszyklus einer Nachricht verstehen: Wenn eine Nachricht in die Warteschlange gestellt wird, tritt sie in den READY ein, und gleichzeitig assoziiert sie einen TTR(time to run) um die Zeit anzugeben, in der die Nachricht ausgeführt wird. Wenn diese Nachricht verzehrt wird, tritt sie in den RESERVED Zustand ein. Nach dem Verbrauch wird die Nachricht gelöscht. Wenn die Verbrauchszeit zu lang, länger als TTR ist, wird das System denken, dass der Verbraucher aufgehängt ist, und dann die Botschaft vom RESERVED Zustand an READY Zustand zurückgibt und an einen anderen Verbraucher zur Wiederaufbereitung übergeben. Daher kann dieselbe Nachricht von mehreren Verbrauchern verarbeitet werden. Der erste Verbraucher, der es verarbeitet hat, kann die Nachricht normal löschen, während die anderen Verbraucher einen Fehler melden, der beim Löschen der Nachricht nicht gelöscht werden kann.
Die Lösung ist sehr einfach. Zunächst müssen Sie sicherstellen, dass TTR -Einstellung nicht zu klein sein kann. Zweitens bietet Beanstalk tatsächlich einen speziellen touch -Befehl, um das Problem der zu langen Ausführungszeit zu lösen. Darüber hinaus müssen wir manchmal auf Anwendungsebene sperren, um die Situation zu vermeiden, in der die gleiche Nachricht gleichzeitig von mehreren Verbrauchern verarbeitet wird.
3. Melden Sie einen Fehler: "Keine Abfrageergebnisse für das Modell"
Wenn Laravel -Lesen und Schreibtrennung aktiviert ist, kann ein Verbraucher bei der Verarbeitung von Nachrichten einen ähnlichen Fehler erhalten. Ein Warteschlangenbefehl mit potenziellen Problemen ist ungefähr wie folgt:
<? phpclass foo erweitert den Befehl implementiert das Selbsthandling, sollte {Verwendung interaktesWithqueue, serializesModels; geschützte $ bar; öffentliche Funktion __construct ($ id) {$ this-> bar = bar :: find ($ id); } public function handle () {// $ this-> bar}}?> Es ist offensichtlich, dass beim Lesen und Schreiben von Laravel-Lesen und Schreiben eingeschaltet wird, aufgrund der Master-Sklaven-Verzögerung, find möglicherweise nicht in der Lage ist, die entsprechenden Daten abzufragen. Sobald wir es hier analysiert haben, ist es wahrscheinlich, dass die Schreibmethode an Folgendes geändert wird:
<? phpclass foo erweitert den Befehl implementiert das Selbsthandling, sollte {Verwendung interaktesWithqueue, serializesModels; geschützte $ bar; öffentliche Funktion __construct ($ id) {$ this-> bar = bar :: OnwriteConnection ()-> find ($ id); } public function handle () {// $ this-> bar}}?> Das heißt, die Abfrage wird über die onWriteConnection -Methode von Laravel an den Hauptserver festgehalten, aber tatsächlich ungültig. Der Kern des Problems ist, dass das System bei der Deserialisierung findOrFail vom Server aufruft.
<? Phpprotected -Funktion getRestoredPropertyValue ($ value) {return $ value InstanceOf modelIdentifier? (Neue $ value-> class)-> fisorFail ($ value-> id): $ value;}?> Weil wir uns nicht in das Framework HACK können, macht onWriteConnection keinen Sinn. Schauen Sie sich das Problem aus einer anderen Perspektive an. Stellen Sie sicher, dass Sie Datenbankobjekte nicht als Attribute verwenden, solange Sie serialisiert sind:
<? phpclass foo erweitert den Befehl implementiert das Selbsthandling, sollte {Verwendung interaktesWithqueue, serializesModels; geschützte $ id; öffentliche Funktion __construct ($ id) {$ this-> id = $ id; } public function handle () {$ bar = bar :: onWriteConnection ()-> find ($ this-> id); }}?>4. Zusammenfassung
Die oben genannten sind mehrere repräsentative Fehlerberichte und Lösungen, die ich bei der Verwendung von Laravel aufgenommen habe. Wenn Sie Fragen haben, können Sie bitte miteinander kommunizieren. Ich hoffe, dieser Artikel wird für das Studium oder die Arbeit aller helfen.