Antworten auf deine Fragen:
Neues Thema erstellen

Funktion wiederholt sich aber returned nur einmal

d3mueller

PC-Freak :D

Hi, ich stehe vor einem unglaublich großen Problem, das seit Wochen besteht. Ich finde diesen blöden Fehler einfach nicht.

Hier erstmal der Code:

PHP:
public static function accessBlueprint($callTime, $params) {
                echo "Anfang der Funktion";
                $playerId = $params["playerId"];
                $locationId = $params["locationId"];
                // blueprintId der hinzuzufügenden Blueprint
                $activateBlueprintId = $params["blueprintId"];
                if (isset($params["levelAtActivation"])) {
                    $levelAtActivation = $params["levelAtActivation"];
                } else {
                    $levelAtActivation = 1;
                }
                self::$database->startTransaction();
                try {
                echo "Wird das HIER WIEDERHOLT <bR><bR><br><br>";
                   
                    // Existiert die Blueprint?
                    $sql = "SELECT count(*), name, blueprintRaceId FROM blueprintData WHERE blueprintId=? LIMIT 0,1";
                    $stmt = self::getConnection()->prepare($sql);
                    $stmt->bind_param('i', $activateBlueprintId);
                    $stmt->execute();
                    $stmt->store_result();
                    $stmt->bind_result($blueprintsRowCount, $blueprintName, $blueprintRaceId);
                    $stmt->fetch();
                   
                    if ($blueprintsRowCount == 0) {
                        // Die Blueprint die aktiviert werden soll, gibt es gar nicht
                        self::$database->rollback();
                        return array("showTime" => 10, "deleteTime" => 0, "linkedId" => 0, "time" => $callTime, "type" => "brightRed", "return" => "Blueprint \"" . $activateBlueprintId . "\" existiert nicht");
                    }
                   
                    // Die Blueprint existiert
                   
                   
                   
                    // Erst die Daten aus blueprintActivations holen
                    $sql = "SELECT activationGroup, activationStage, activationResearchId, activationRaceId FROM researchActivations WHERE blueprintId=? AND bodyplanId = 0 LIMIT 0,1";
                    $stmt = self::getConnection()->prepare($sql);
                    $stmt->bind_param('i', $activateBlueprintId);
                    $stmt->execute();
                    $stmt->store_result();
                    $stmt->bind_result($activationGroup, $activationStage, $activationResearchId, $activationRaceId);
                    $stmt->fetch();
                   
                    // Existiert schon eine Group dieser Blueprint bei dem Benutzer?
                    $sql = "SELECT blueprintGroup, blueprintStage FROM blueprints WHERE blueprintGroup=? AND groupResearchId=? AND groupRaceId=? LIMIT 0,1";
                    $stmt = self::getConnection()->prepare($sql);
                    $stmt->bind_param('iii', $activationGroup, $activationResearchId, $activationRaceId);
                    $stmt->execute();
                    $stmt->store_result();
                    $stmt->bind_result($userBlueprintGroup, $userBlueprintStage);
                    $stmt->fetch();
                   
                    echo "wird das wiederholt bei der Fehlermeldung?";
                   
                    if ($stmt->affected_rows == 0) {
                        // Gruppe existiert noch nicht
                        echo "userBlueprintGroup: " . $userBlueprintGroup . " | userBlueprintStage: " . $userBlueprintStage . "<br>";
                       
                        // Neue Gruppe muss erstellt werden
                        $sql = "INSERT INTO blueprints (playerId, locationId, blueprintId, groupResearchId, groupRaceId, blueprintGroup, blueprintStage, level, raceId) VALUES (?,?,?,?,?,?,?,?,?)";
                        $stmt = self::getConnection()->prepare($sql);
                        $stmt->bind_param('iiiiiiiii', $playerId, $locationId, $activateBlueprintId, $activationResearchId, $activationRaceId, $activationGroup, $activationStage, $levelAtActivation, $blueprintRaceId);
                        $stmt->execute();
                        $stmt->store_result();
                       
                        if ($stmt->affected_rows != 1) {
                            // Ein Fehler ist passiert
                            self::$database->rollback();
                            return array("showTime" => 20, "deleteTime" => $callTime + 5, "linkedId" => 0, "time" => $callTime, "type" => "darkRed", "return" => "Es gab einen Fehler beim Erstellen einer neuen Gruppe. Bitte Admin melden");
                        }
                       
                        // Alles okay
                        self::$database->commit();
                        echo "TEST TEST TEST <br><br>";
                        return array("showTime" => 10, "deleteTime" => 0, "linkedId" => $activateBlueprintId, "time" => $callTime, "type" => "brightBlue", "return" => "Blueprint \"" . $blueprintName . "\" freigeschaltet. Es handelt sich um eine neue Technik");
                        echo "<br>Das hier sollte NICHT zu sehen sein<br><br>";
                    } else {
                        // Gruppe existiert schon
                       
                        // Prüfen, ob die Stage der zu aktivierenden Blueprint größer ist, als die schon vorhandene
                        if ($activationStage <= $userBlueprintStage) {
                            echo "<br><br>" . $activationStage . "<= ActivationStage" . " || UserBlueprintStage =>" . $userBlueprintStage;
                            // Die Stage der zu aktivierenden Blueprint ist kleiner oder gleich, also darf sie nicht aktiviert werden
                            self::$database->rollback();
                            return array("showTime" => 10, "deleteTime" => $callTime + 60, "linkedId" => 0, "time" => $callTime, "type" => "brightRed", "return" => "Blueprint \"" . $blueprintName . "\" ist veraltet und wird nicht freigeschaltet.");
                        }
                       
                        // Wenn es bis hier kommt, dann ist die Stage größer und die Blueprint kann freigeschaltet werden. Da die Gruppe schon existiert, muss nur noch ein Update eingefügt werden.
                        $sql = "UPDATE blueprints SET blueprintId=?, blueprintStage = ? WHERE blueprintGroup=? AND groupResearchId=? AND groupRaceId=?";
                        $stmt = self::getConnection()->prepare($sql);
                        $stmt->bind_param('iiiii', $activateBlueprintId, $activationStage, $activationGroup, $activationResearchId, $activationRaceId);
                        $stmt->execute();
                        $stmt->store_result();
                       
                        if ($stmt->affected_rows != 1) {
                            // Irgendwas hat nicht funktioniert
                            self::$database->rollback();
                            return array("showTime" => 20, "deleteTime" => $callTime + 60, "linkedId" => 0, "time" => $callTime, "type" => "darkRed", "return" => "Es gab einen Fehler bei der Aktualisierung der Blueprint-Tabelle. Bitte Admin melden");
                        }
                       
                       
                        // Alles ist gut gelaufen und aktualisiert
                        self::$database->commit();
                        return array("showTime" => 10, "deleteTime" => 0, "linkedId" => $activateBlueprintId, "time" => $callTime, "type" => "brightBlue", "return" => "Blueprint \"" . $blueprintName . "\" freigeschaltet. Es handelt sich um ein Upgrade");
                       
                       
                    }
                   
                   
                } catch (Exception $e) {
                    self::$database->rollback();
                    throw new Exception(__METHOD__." | ".$e->getMessage());
                }
            }


Die Funktion soll einfach Blueprints für den Benutzer freischalten. Blueprints sind einfach Zeilen in der Datenbank, mit verschiedenen Informationen. Und es gibt eine Tabelle blueprints, in der die freigeschalteten Blueprints für jeden Spieler eingetragen werden (im Prinzip wird da dann die User-Id und die jeweilige Blueprint-Id eingetragen, und halt noch Details dazu).

Die Blueprints sind in Gruppen organisiert und so aufgebaut:

Blueprint 1 - Gruppe 1 - Stage 1
Blueprint 2 - Gruppe 1 - Stage 2 => Ist ein Upgrade zur vorherigen Blueprint, also soll keine neue Zeile in der blueprints-Tabelle erstellt werden, sondern nur die bestehende (von der vorherigen) aktualisiert werden
Blueprint 3 - Gruppe 2 - Stage 1 => Neue Gruppe, also neue Zeile in der blueprints-Tabelle


Die Funktion schaut, ob die BlueprintId, die freigeschaltet werden soll, bereits in der blueprints-Tabelle für den jeweiligen Nutzer existiert, bzw. ob es die Gruppe dieser blueprint schon gibt. Wenn nicht, erstellt sie sie und wenn ja, dann aktualisiert sie sie.

Zusätzlich schaut sie, ob das Stage (sozusagen das Level) auch wirklich höher ist, weil sonst macht es keinen Sinn, die zu aktualisieren. Wenn das Level kleiner/gleich der bereits in der Datenbank verfügbaren ist, dann kommt die Meldung "Blueprint "Blueprint 1" ist veraltet und wird nicht freigeschaltet"

Jetzt ist es aber so, dass die Funktion manchmal(!) folgendes macht:

Angenommen, die freizuschaltende Blueprint gehört einer neuen Gruppe an.
Das erkennt die Funktion richtig und erstellt eine neue Zeile. Dann gelangt sie zur Stelle, an der sie returnen sollte, mit der Meldung "Blueprint "Blueprint 1" freigeschaltet. Es handelt sich um eine neue Technik".

Aber stattdessen fängt sie einfach von vorne an und überprüft nochmal, ob es die Gruppe schon gibt. Da sie ja gerade erstellt wurde, springt sie zum Zweig, in dem sie die Gruppe aktualisieren soll. Aber die Stages sind da ja identisch und somit springt die Funktion zum Zweig, in dem sie sagt, dass die Blueprint veraltet ist. Und hier funktioniert der return-Befehl und die Nachricht wird zurückgegeben.

Ich verstehe nicht, warum die Funktion sich einfach so komplett wiederholt, aber nur einmal returned. Ich habe schon ausgeschlossen, dass sie zweimal aufgerufen wird (was aber das mit dem return immer noch nicht erklären würde).

Wie ihr seht, habe ich mehrmals echo-Ausgaben gemacht und daran habe ich damals erkannt, dass sich die Funktion wiederholt. Es wird dann z.B. sowas ausgegeben (nicht sehr professionell :D, ich weiß)

Anfang der FunktionWird das HIER WIEDERHOLT



wird das wiederholt bei der FehlermeldungHIER NACHSCHAUEN: userBlueprintGroup: 0 | userBlueprintStage: 0
TEST TEST TEST

Anfang der FunktionWird das HIER WIEDERHOLT



wird das wiederholt bei der Fehlermeldung

1<= ActivationStage || UserBlueprintStage =>1

Ich habe auch schon überlegt, ob es was mit den transactions zu tun hat, dass er z.B. die Funktion wiederholt, wenn die transaction "rollback"ed wird. Aber der rollback-Befehl funktioniert, es wird kein Fehler zurückgegeben o.ä. Und selbst wenn, müsste er dann nicht bei Beginn der transaction wieder anfangen? Das tut er ja nicht.

Ich weiß halt auch nicht, wie ich diesen Fehler auslöse. Es hängt nicht mit bestimmten Blueprints zusammen, es hängt nicht mit bestimmten Zeiten zusammen, und es hängt nicht mit fehlerhaften Datenbank-daten zusammen. Das habe ich alles weitesgehend überprüft. Ich bin komplett ratlos und am verzweifeln :/


Vielen Dank für eure Hilfe

Lg
d3mueller
 

Duddle

Posting-Frequenz: 14µHz

Naja, ohne Zugriff zur Datenbank und zum Code wird das schwierig nachzuvollziehen und damit zu debuggen. Zwei Ansätze sind mir beim Überfliegen deines Codes und Beitrages aufgefallen:

1. wenn du Transaktionen benutzt, stell sicher, dass du kein autocommit hast, sonst hilft auch ein explizites Rollback nicht
2.
Aber stattdessen fängt sie einfach von vorne an
Prüfe, wer wo die Funktion accessBlueprint() aufruft. Da sie sich nicht selbst aufruft, muss die Wiederholung von "extern" kommen.


Duddle
 

d3mueller

PC-Freak :D

1. war es nicht, aber 2. hat mein Problem jetzt gelöst :D Danke

Folgendes: Ich habe ich eine Funktion, die zeitlich gesteuerte Events ausführen soll.
Also man hat in der Datenbank gespeichert, dass zur Zeit X das Event Y ausgeführt werden soll. Und ist die Zeit verstrichen, wird es eben ausgeführt.

Und zwar ist das so, das der Event-Klasse vorher gesagt wird, welche Funktion/Methode sie bei welchem Event aufrufen soll(ich registriere also EventHandler) (Wenn das Event "accessBlueprint" heißt, soll die Methode "accessBlueprint" aufgerufen werden). Diese Informationen werden in einem Array $events gespeichert, das global in der Klasse verfügbar ist. Darauf greift dann die handleEvent-Methode(welche das Event ausführen soll) zu und schaut, welche Methode sie eben aufrufen muss. Und dabei kann es eben sein, dass bei einem bestimmten Event nicht nur 1 Methode, sondern 2 oder mehr Methoden nacheinander aufgerufen werden sollen. Das ist auch so gewollt.

Das Problem entstand jetzt folgendermaßen:
Ich habe eine Schleife, die die Events aus der Datenbank ausliest und dann der handleEvent-Methode einzeln übergibt. Und bei jedem Durchlauf der Schleife, registriere ich diese EventHandler, damit die handleEvent-Methode weiß, was sie bei den Events machen muss.

Und wenn jetzt die Schleife zweimal durchläuft, werden die EventHandler zweimal registriert. Also sind bei jedem Event jetzt 2 Methoden eingetragen, die ausgeführt werden sollen. Und zwar zweimal die gleiche. Daher wurde accessBlueprint() auch zweimal ausgeführt. Das war der Fehler :D

Ich hoffe, es ist einigermaßen verständlich. Es ist sehr schwer das einfach so zu erklären, da es ziemlich komplex ist.

Aber auf jeden Fall vielen Dank für den Anstupser mit dem zweimaligen Aufrufen. :D
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Neueste Themen & Antworten

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
118.616
Beiträge
1.538.358
Mitglieder
67.536
Neuestes Mitglied
QuestionMark
Oben