![]() |
[PHP/MySQL] - commit klappt nicht
Hi!
Ich bin verwirrt. Ich habe folgendes Statement:
PHP-Quellcode:
Ein einfaches 0815-Select. Das Ganze soll in einer Transaktion laufen, mit was anderem zusammen, aber das ist hier unerheblich (will heißen, das andere geht einwandfrei - sicher!).
$db -> autocommit(false);
$sql2 = $db->prepare('SELECT active FROM course_registrations WHERE participantId=? AND courseId=?'); $sql2 -> bind_param('ii', $participantID, $courseID); $sql2 -> execute(); $sql2 -> bind_result($active); $sql2 -> fetch(); if ($db -> commit()) { } else { //echo $active; echo "ARGH"; } Aber das hier oben klappt nicht. Ich habe keine Idee mehr, woran es noch liegen könnte. Kopiere ich das Statement raus und schiebe es per phpMyAdmin in die DB läuft es einwandfrei. Selbst wenn ich mir $active ausgeben lasse (die Kommentarzeile einkommentiere), liefert es den richtigen Wert. Also klappt das Statement an sich ja?! Im Error steht auch nix drin - ich verstehe die Welt nicht mehr (oder so ähnlich)... Wer hilft mir vom Schlauch runter? Liebe Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
Musst du die Transaktion vielleicht vorher starten?
|
AW: [PHP/MySQL] - commit klappt nicht
Hi!
Nein, das muss man bei mysqli nicht machen. Wie gesagt funktioniert es auch mit dem anderen Teil der TA und auch anderen, die ich verwende... Liebe Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
Bei einem Select gibt es ja eigentlich auch nichts zum comitten
|
AW: [PHP/MySQL] - commit klappt nicht
Das habe ich mir auch schon gedacht.
Ich erzähl mal die ganze story. Ich mach ein Update in der DB und möchte dann den geänderten Wert auslesen. Das muss ich zusammen in einer Transaktion machen, damit mir keiner dazwischen fummeln kann. Und das muss ja irgendwie gehen... Aber wenn das SELECT drin ist, gehts schief... Oder gibt es einen anderen Weg? Liebe Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
Zitat:
![]() Greetz alcaeus |
AW: [PHP/MySQL] - commit klappt nicht
Es scheint ihm eher darum zu gehen, sicherzustellen, den geänderten Satz zu bekommen.
Das sollte mit last_inserted_id() gehen ( auch wenn der Name der Funktion es nicht unbedingt Erraten lässt) |
AW: [PHP/MySQL] - commit klappt nicht
Hi,
hmm, gibt es da wirklich keine andere Möglichkeit? Wenn ich die Doku richtig lese, habe ich ja nur die Möglichkeit, die komplette Tabelle zu locken. Das ist ja doch schon deutlich "härter", als im Rahmen einer TA, die ja deutlich feinkörniger arbeiten kann... @Markus: last_insert_id funktioniert nur bei auto_inc Feldern und (wie der Name doch vermuten lässt ;) ) nur bei Inserts - zumindest laut Doku. Außerdem brauche ich auch nicht die id, sondern ein anderes Feld. Liebe Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
Dann frag halt die Updatebedingung im Select ab
|
AW: [PHP/MySQL] - commit klappt nicht
Hi!
Wie meinst du? In welchem Select soll ich was fragen? Liebe Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
SQL-Code:
Select Active from course_registrations WHERE <Bedingung des Updatebefehls>;
|
AW: [PHP/MySQL] - commit klappt nicht
Moin,
also, wenn du einen Update und anschliessenden Select machst und nicht willst, dass da ein anderer Update-Prozess dazwischenkommt, dann musst du definitiv mit Locks arbeiten. Transaktionen sind nur fuer Inserts und Commits, und ohne Locks kann dir ein anderer Update-Prozess dazwischenfunken. Je nach Anwendungsfall ist es aber besser, den finalen Wert anzuzeigen, also inkl. eines eventuellen zwischenzeitlichen Updates. Greetz alcaeus |
AW: [PHP/MySQL] - commit klappt nicht
Hi!
Das ist doch exakt das, was ich oben tue?! Nur genau das funktioniert ja nicht. Oder zumindest führt es dazu, dass die Transaktion failed und dann ein rollback macht. @alcaeus: Ok, "schade" Und es gibt auch keinen feinkörnigeren Lock als gleich die ganze Tabelle? Den finalen Wert hier auszugeben, ist leider keine Option an dieser Stelle. Ich muss gezielt dieses Update reflektieren. Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
Ist es denn sehr wahrscheinlich, dass jemand anderes genau diesen Satz gleichzeitig updatet?
|
AW: [PHP/MySQL] - commit klappt nicht
Hi!
In der Vergangenheit hat sich gezeigt, dass Nutzer dazu neigen, Links mit Doppelklicks auszuführen und da sind schon komische Konstellationen zustande gekommen. Ich kann nicht genau sagen, ob es damit zu lösen ist, aber ich will es so fehlerfrei wie irgend möglich machen. Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
Bei einem Doppelklick würde dsann aber 2 Mal der selbe Updatebefehl durchgeführt
|
AW: [PHP/MySQL] - commit klappt nicht
Werden diese MultiQuery zusammen verarbeitet oder kann da eine andere Abfrage dazwischenfunken?
![]() |
AW: [PHP/MySQL] - commit klappt nicht
Hi!
Nein, leider nicht:
SQL-Code:
UPDATE course_registrations SET active = NOT active WHERE participantId=? AND courseId=?
@himitsu: Nach meinem Kenntnisstand ist das nicht transaktionssicher. Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
Zitat:
Greetz alcaeus |
AW: [PHP/MySQL] - commit klappt nicht
Na dann ist das natürlich ungeschickt
|
AW: [PHP/MySQL] - commit klappt nicht
Zitat:
Bei READ gibt es die Moeglichkeit, so genannte "non-conflicting inserts" zu erlauben, write-Locks gelten aber immer fuer die ganze Tabelle. Da du hier aber eine relativ kurze und unkritische Critical Section hast, duerfte ein Table-Lock erst bei hoher Last auffallen. Du hast schliesslich keine Key-Updates, und wenn die Where-Bedingung von Update und Select als gesamter Key vorhanden sind, gibt es da wirklich keine Performance-Probleme. Greetz alcaeus |
AW: [PHP/MySQL] - commit klappt nicht
Hi,
Zitat:
Liebe Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
Zitat:
Greetz alcaeus |
AW: [PHP/MySQL] - commit klappt nicht
Hi!
Gut, soweit ;) Jetzt sehe ich nur ein Problem: Die Doku sagt: Zitat:
Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
Moin,
ganz kurz das Prozedere:
SQL-Code:
Ich bin mir grad nicht ganz sicher wie das Verhalten bei autocommit = 0 ist - eventuell musst du nach dem Update aber noch vor dem Select einen Commit machen bzw. auch vor dem Update noch eine Transaktion oeffnen. Ganz aussen rum ist der autocommit, dann dein Lock, anschliessend die Queries die du ausfuehren willst.
SET AUTOCOMMIT = 0;
LOCK TABLES course_registrations WRITE; UPDATE course_registrations...; SELECT active FROM course_registrations...; UNLOCK TABLES course_registrations; SET AUTOCOMMIT = 1; Beachte aber, dass du den Unlock direkt nach dem Select machst und noch bevor du die Daten verarbeitest, damit du die Tabelle nicht laenger als noetig benutzt. Beachte ausserdem dass du vor dem Unlock keine Tabelle benutzen kannst die nicht vorher gelockt wurde. Greetz alcaeus |
AW: [PHP/MySQL] - commit klappt nicht
Das Transaktionshandling bei MySQL erscheint mir etwas umständlich und suboptimal
|
AW: [PHP/MySQL] - commit klappt nicht
Zitat:
Greetz alcaeus |
AW: [PHP/MySQL] - commit klappt nicht
Sorry dass ich mir überhaupt erlaubt habe etwas zu schreiben.
|
AW: [PHP/MySQL] - commit klappt nicht
Hi!
Irgendwo muss ein Haken sein:
PHP-Quellcode:
Egal an welchen der beiden Stellen das UNLOCK steht - das Ergebnis ist immer ein ARGH...
$db -> autocommit(false);
$db -> query("LOCK TABLES course_registrations WRITE"); $sql = $db -> prepare('UPDATE course_registrations SET active = NOT active WHERE participantId=? AND courseId=?'); $sql -> bind_param('ii', $participantID, $courseID); $sql -> execute(); $sql2 = $db->prepare('SELECT active FROM course_registrations WHERE participantId=? AND courseId=?'); $sql2 -> bind_param('ii', $participantID, $courseID); $sql2 -> execute(); $db -> query("UNLOCK TABLES course_registrations"); $sql2 -> bind_result($active); $sql2 -> fetch(); if ($db -> commit()) { } else { echo $active; echo "ARGH"; } //$db -> query("UNLOCK TABLES course_registrations"); $db -> autocommit(true); Grüße, Frederic |
AW: [PHP/MySQL] - commit klappt nicht
Zitat:
Es ist nunmal einfach etwas "unlogisch", "kompliziert", "doof", "ungeschickt", was auch immer zu nennen. Wenn du die letzten paar PHP-Themen hier in der DP ansatzweise verfolgt hast weisst du auch was dabei rauskommt: irgendwer liest es und nimmts fuer bare Muenze. Es spricht nichts gegen eine Diskussion ueber das Thema - aber wenn dann bitte mit Argumenten. Zum Thema: 1. Den fetch() solltest du vor dem Unlock ausfuehren. 2. Die Logik hat nen kleinen Denkfehler: wenn autocommit = 0 musst du das Update-Statement mit nem Commit bestaetigen. Das musst du vor dem Select machen, ansonsten ist die Aenderung ja noch nicht in der DB. Greetz alcaeus |
AW: [PHP/MySQL] - commit klappt nicht
Hi!
Ja, da habe ich natürlich jetzt auf dem Schlauch gestanden. Danke dir fürs runterheben ;) Die augenscheinlich funktionierende Version sieht jetzt so aus:
PHP-Quellcode:
Vllt. magst du ja nochmal drüberschauen und sagen, ob es noch was zu verbessern gibt.
$db -> autocommit(false);
$db -> query("LOCK TABLES course_registrations WRITE"); $sql = $db -> prepare('UPDATE course_registrations SET active = NOT active WHERE participantId=? AND courseId=?'); $sql -> bind_param('ii', $participantID, $courseID); $sql -> execute(); if ($db -> commit() && $sql -> affected_rows == 1) { $sql -> close(); $sql2 = $db->prepare('SELECT active FROM course_registrations WHERE participantId=? AND courseId=?'); $sql2 -> bind_param('ii', $participantID, $courseID); $sql2 -> execute(); $sql2 -> bind_result($active); $sql2 -> fetch(); $sql2 -> close(); $db -> query("UNLOCK TABLES"); $db -> autocommit(true); $owner = getLeaderForCourseId($db, $courseID); sendMessage($db, $owner, $participantID, $active?20:21, $active?$langActivated:$langDeactivated, $_GET['cid']); return 1; } else { $sql -> close(); $db -> query("UNLOCK TABLES"); $db -> autocommit(true); return 0; } Liebe Grüße, Frederic |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz