Ich habe eine PHP-Routine, die ich immer zum Ausführen eines SQL verwende. Eine ähnliche Routine frägt auch Daten ab. Dabei wird die Verbindung immer mit mysql_connect() aufgebaut.
Jetzt möchte ich verhindern, dass während einer, mehrere Befehle andauernden, Aktion die Tabelle für andere User (und deren Aktionen) zugreifbar ist. Dazu kann ich ja eigentlich LOCK TABLES verwenden. Aber in der Doku steht, dass dann nur der selbe Thread zugreifen kann und andere Threads gesperrt sind. Durch meine Routine ist aber jeder Zugriff ein neuer Thread:
Code: Alles auswählen
// hier würde ich gerne Sperren
ExecuteSQL("UPDATE id FROM tbltest SET test=5 WHERE UserID=1");
echo "ThreadID: " . mysql_thread_id() . "<br>";
// Andere Funktionen in anderen Includes die zwischendurch auch
// mal zB ExecuteSQL aufrufen oder auch andere DB-Funktionen verwenden.
// Genaugenommen fünf mal was anderes machen was innerhalb
// des Locks funktionieren soll. Wenn aber mittendrin ein anderer
// User die selbe Funktionalität benötigt, sollte der bereits laufende
// Prozess erst Fertiggestellt werden bevor das beim anderen User
// anläuft.
ExecuteSQL("UPDATE id FROM tbltest SET test=1 WHERE UserID=1");
echo "ThreadID: " . mysql_thread_id() . "<br>";
// und hier die Sperre aufheben
ThreadID: 304397
ThreadID: 304402
Wie kann ich MySQL Verbindungen Userbezogen verwalten? Oder ist das gar nicht nötig? Wie würdet Ihr das lösen?
Meine Routine:
Code: Alles auswählen
// Does a SQL-Execute to the database.
// Returns true in case of success, false in case of failure.
function ExecuteSQL($SQL) {
$DBCONN = mysql_connect (DBHOST, DBUSER, DBPASSWORD);
if ($DBCONN == FALSE) {
// can not open database!
error_log("DATABASE: Can not open database " . DBHOST . " for execute.");
error_log("DATABASE: error-details: " . mysql_errno() . " / " . mysql_error());
return FALSE;
}
mysql_select_db(DBDATABASE, $DBCONN);
$DBERG = mysql_query($SQL, $DBCONN);
if ($DBERG == FALSE) {
error_log("DATABASE: Error while executing " . $SQL);
error_log("DATABASE: error-details: " . mysql_errno() . " / " . mysql_error());
$Ergebnis = FALSE;
} else {
$Ergebnis = TRUE;
@mysql_free_result($DBERG);
}
return $Ergebnis;
}
Das Problem entsteht durch das Kapseln der Funktion in ExecuteSQL(). Aber ich habe enorm viele Vorteile durch diese Kapselung, kann Datenbanksachen besser warten und spare auch Mengen an Code. Aber kann ich so weder Transaktionen noch Locks verwenden?
Volker