Kerstin: gleichzeitiges Lesen/Schreiben einer XML-Datei?

Hallo alle miteinander,

beim Lesen des Beitrags von JCB zum Thema "gleichzeitiges Lesen einer Datei möglich?", ist mit damit ein Problem wieder in den Vordergrund gerückt, welches ich leider ein wenig vernachlässigt habe. Ich hab dort auch gefragt, ob der Ersteller des Beitrags denn ein paar Tipps für mich hätte, wie dies umgesetzt werden kann, habe dann aber gemerkt, dass das vielleicht zu allgemein gehalten ist. Deshalb fange ich mal einen neuen Thread an, da es vielleicht doch etwas anders ist als gedacht ...

Lange Vorrede, kommen wir also zum eigentlichen Problem:

Ich nutze die DOM-Funktionen von PHP, um auf eine XML-Datei zuzugreifen, sie zu manipulieren und wieder zurückzuschreiben. Das geht folgendermaßen:
<<PHP
  //Pfad zur XML-Datei definieren
  define(PATH, '../manualdata/test.xml');

//XML-Datei laden
  $doc = new DOMDocument;
  $doc->load(PATH);

//XPath für Abfrage setzen
  $xpath = new DOMXPath($doc);

$queries[] = "//ManualData/System[@systemId=3]";
  $queries[] = "//ManualData/System/Dependences/dependence[@systemId=3]";

//Schleife, welche Knoten löscht
  foreach ($queries as $query) {
   $nodes = $xpath->query($query);
   foreach ($nodes as $n) {
     $n->parentNode->removeChild($n); }
  }//end foreach

//XML-Datei schreiben - Variante [1]
  $doc->save(PATH);

//XML-Datei schreiben - Variante [2]
  $fh = fopen(PATH, 'w');
  fwrite($fh, $doc->saveXML());
  fclose($fh);
PHP>>

Dabei wird die bereits vorhandene Datei ersetzt und die mit DOMDocument geladene XML-Datei wieder in die selbe geschrieben. Gleichzeitig kann es natürlich vorkommen, dass darauf lesend, aber auch schreibend zugegriffen werden kann.
Die Frage oder eine Frage: In welchem Fall ist es nötig beim Schreiben eine Sperre zu setzen? Ist es überhaupt nötig?
In PHP gibt es die Funktion flock, die die Sperre beim Schreiben vornehmen könnte (bei Variante 2). Allerdings bleibt dabei die Frage, wie reagiert dann der Nächste, der zur selben Zeit lesend oder schreibend auf die XML-Datei zugreifen möchte? Wird er total abgewiesen oder wartet er bis die Datei wieder frei wird und nimmt dann seinen Zugriff vor?

Gruß,
Kerstin

  1. Hallo,

    ...
    Lange Vorrede...

    ja!

    ...
    ...
    Die Frage oder eine Frage: In welchem Fall ist es nötig beim Schreiben eine Sperre zu setzen? Ist es überhaupt nötig?

    Es ist jedenfalls notwendig.

    ... flock ... Frage, wie reagiert dann der Nächste, der zur selben Zeit lesend oder schreibend ... zugreifen möchte?  Wird er total abgewiesen oder wartet er bis die Datei wieder frei wird und nimmt dann seinen Zugriff vor?

    Der nächste _Prozess_ wartet, bis die Sperre aufgehoben wird. In Threads sieht die Sache anders aus!

    Gruß aus Berlin!
    eddi

    1. echo $begrüßung;

      ... flock ... Frage, wie reagiert dann der Nächste, der zur selben Zeit lesend oder schreibend ... zugreifen möchte?  Wird er total abgewiesen oder wartet er bis die Datei wieder frei wird und nimmt dann seinen Zugriff vor?

      Der nächste _Prozess_ wartet, bis die Sperre aufgehoben wird. In Threads sieht die Sache anders aus!

      Nach Lektüre der Handbuchseite zu flock() hätte ich ja behauptet, dass das Warten zwar Standard-Verhalten ist, man aber auch ein nicht blockierendes Verhalten auswählen kann.

      echo "$verabschiedung $name";

      1. Nach Lektüre der Handbuchseite zu flock() hätte ich ja behauptet, dass das Warten zwar Standard-Verhalten ist, man aber auch ein nicht blockierendes Verhalten auswählen kann.

        Ich hätte jetzt LOCK_EX gewählt, um eine schreibende Verriegelung zu setzen. Ich interpretiere das so, dass weitere Prozesse, die ebenfalls in die Datei schreiben wollen, warten müssten, bis die Verriegelung aufgehoben ist, der Vorgänger also fertig ist mit schreiben.

        Während ich das schreibe, fällt mir ein, das es ja eigentlich Blödsinn ist, einen weiteren Prozesse gleichzeitig lesen zu lassen, weil steht ja nüscht drin in der Datei. Die wird ja erst nach und nach wieder gefüllt. Naja, das geht ja eigentlich schon recht flott und in einem Schwung. Heißt LOCK_EX nun, komplette Verriegelung oder muss zusätzlich noch LOCK_SH gesetzt werden?

        Gruß,
        Kerstin

    2. Hallo,

      Die Frage oder eine Frage: In welchem Fall ist es nötig beim Schreiben eine Sperre zu setzen? Ist es überhaupt nötig?

      Es ist jedenfalls notwendig.

      Immer? bei $doc->save(PATH); und auch bei $doc->saveXML(PATH);? Bei letzterem Nutze ich ja die "File"-Funktionen von PHP. Da wärs mir klar. Die Frage ist, was passiert bei save? Im PHP-Manual habe ich leider dazu nichts gefunden.

      ... flock ... Frage, wie reagiert dann der Nächste, der zur selben Zeit lesend oder schreibend ... zugreifen möchte?  Wird er total abgewiesen oder wartet er bis die Datei wieder frei wird und nimmt dann seinen Zugriff vor?

      Der nächste _Prozess_ wartet, bis die Sperre aufgehoben wird. In Threads sieht die Sache anders aus!

      Gut. Was meinst du mit Threads?

      Grüße aus Potsdam,
      Kerstin

      1. Re:

        Es ist jedenfalls notwendig.

        Immer?

        jedenfalls notwengig = notwendg in jedem Fall

        bei $doc->save(PATH); und auch bei $doc->saveXML(PATH);?

        Ja, weil Du nicht ausschließen kannst, das die Datenmenge größer ist als der Schreibbuffer. In einem solchen Fall kann es passieren, das der I/O-Scheduler nach Schreiben des Buffers einem anderen Prozess gewährt, den noch nicht vollständigen Inhalt auszulesen, was in Deinem Fall zu einem XML Parse Error führen würde.

        Die Frage ist, was passiert bei save?

        Es werden die Daten im XML-Format geschreiben.

        ... flock ... Frage, wie reagiert dann der Nächste, der zur selben Zeit lesend oder schreibend ... zugreifen möchte?  Wird er total abgewiesen oder wartet er bis die Datei wieder frei wird und nimmt dann seinen Zugriff vor?
        Der nächste _Prozess_ wartet, bis die Sperre aufgehoben wird. In Threads sieht die Sache anders aus!

        Gut. Was meinst du mit Threads?

        Wikipedia

        Gruß aus Berlin!
        eddi

        1. Hallo,

          bei $doc->save(PATH); und auch bei $doc->saveXML(PATH);?

          Ja, weil Du nicht ausschließen kannst, das die Datenmenge größer ist als der Schreibbuffer. In einem solchen Fall kann es passieren, das der I/O-Scheduler nach Schreiben des Buffers einem anderen Prozess gewährt, den noch nicht vollständigen Inhalt auszulesen, was in Deinem Fall zu einem XML Parse Error führen würde.

          Die Frage ist, was passiert bei save?

          Es werden die Daten im XML-Format geschreiben.

          Das war schon klar. Vielleicht anders gefragt: Wenn ich save nutze, wird dabei automatisch das File gesperrt? Sollte es nicht eigentlich so sein? Weil es wird ja definitiv was geschrieben in eine Datei, da sollte dann doch auch gleich mitgedacht worden sein, und die Datei, in die gerade geschrieben wird, gesperrt werden.

          Gruß aus Potsdam,
          Kerstin

          1. Hallo,

            Es ist jedenfalls notwendig.
            Das war schon klar. Vielleicht anders gefragt: Wenn ich save nutze, wird dabei automatisch das File gesperrt?

            nein.

            Sollte es nicht eigentlich so sein?

            Nein.

            Weil es wird ja definitiv was geschrieben in eine Datei, da sollte dann doch auch gleich mitgedacht worden sein, und die Datei, in die gerade geschrieben wird, gesperrt werden.

            Dafür hat der Programmierer zu sorgen, und das bist in dem Fall Du.

            Gruß aus Berlin!
            eddi