PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mit PHP/MySQL einen Datensatz direkt nach "insert" lesen


Ben Carter
2023-05-17, 20:48:36
Hallo!

Da ich in den letzten Jahren fast nur noch mit SQL Server gearbeitet habe, bin ich bei MySQL etwas eingerostet.

Folgendes Problem:

Ich mache ein Insert in eine Tabelle. Unter anderem mit einer GUID. Direkt nach dem Insert will ich diesen Datensatz anhand der GUID wieder lesen. Für beide Queries verwende ich Prepared Statements.

Der Datensatz ist aber nicht direkt vorhanden.
Nach dem Insert schließe ich das Statement und führe auch ein Commit aus. Wenn ich eine Sekunde warte (mit sleep) funktioniert es. Aber das kann nicht Sinn der Sache sein.

Wie löst man das ordentlich?

Auszug aus der Methode:

$sql = "INSERT INTO user (guid, username, password, salt, email, avatarUrl, discordId, registerDate) VALUES (?, ?, ?, ?, ?, ?, ?, NOW());";
$statement = DB::$db->prepare($sql);
$statement->bind_param('sssssss', $guid, $username, $password, $salt, $email, $avatarUrl, $discordId);

$result = $statement->execute();
$statement->close();
DB::$db->commit();

if ($result) return $this->getUserByGuid($guid);

public function getUserByGuid($guid)
{
$sql = "SELECT * FROM user WHERE guid = ?;";
$statement = DB::$db->prepare($sql);
$statement->bind_param('s', $guid);

$statement->execute();
$result = $statement->get_result();

$rows = $result->fetch_all(MYSQLI_ASSOC);

if (count($rows) == 0) return false;
else return $rows[0];
}


Wenn ich eben vor dem Aufruf der Methode getUserByGuid ein "sleep(1);" einfüge, klappt's.

Langsam bringt mich das zum Verzweifeln...

Vielen Dank,
lg Ben

pest
2023-05-17, 21:40:49
nach 10min PHP lernen würde ich sagen


$statement->close();
DB::$db->commit();


sind überflüssig

wieso machst du ein commit? du nimmst doch PDO
der Eintrag ist nach $result = $statement->execute(); verfügbar.

es kann natürlich auch sein, dass dein select und dein insert durch eine andere connection zum db-server gemanaged werden, den code sehe nicht.
dadurch könnte es u.u: im Millisekundenbereich zu Problemen kommen.

Ben Carter
2023-05-17, 21:57:47
Die beiden Befehle habe ich hinzugefügt, nachdem ich eben auf das Problem gestoßen bin. Vorher habe ich sie nicht genutzt.

Es ist immer das gleiche Connection-Objekt. Vermutlich mach mysqli im Hintergrund aber eine weitere Verbindung auf. Anders kann ich mir das nicht wirklich erklären.

MORPHiNE
2023-05-17, 22:12:32
Vom Ablauf korrekt wären erst Commit und dann Close.
Macht es einen Unterschied zur Laufzeit, wenn du die Zeilen vertauschst?
Dürfte es aber nur, wenn du nicht eh autocommit fährst.

mysqli unterstützt Connection Pooling, sollte hier aber keine Rolle spielen.
Falls die korrekte Reihenfolge von Commit und Close keinen Einfluss hat, ist das Stichwort an der Stelle m.E. Transaction Isolation Levels (https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html).

Ben Carter
2023-05-17, 22:19:12
Tatsache, das tauschen der beiden Zeilen hat geholfen.

Danke sehr!

Geldmann3
2023-07-13, 20:01:15
Noch ein Tipp, wenn du mit Datenbanken arbeitest: Achte immer auf die Fehlerbehandlung. Es ist eine gute Praxis, die Ausführung von SQL-Anweisungen in einem Try/Catch-Block zu kapseln und entsprechende Fehlermeldungen zu loggen oder zu behandeln. So kannst du Probleme leichter diagnostizieren und beheben.