Raketenleichtmatrose: PHP PDO:SQLITE - Falle: attempt to write a readonly database - und kein TRUNCATE table in SQLITE

Ich bin gerade über folgende Falle gestolpert:

Der Connect mit

$pdo = new PDO( 'sqlite:' . $SQLite3File )

hat funktioniert.

Aber jeder Versuch, an der Datenbank etwas zu ändern warf nur folgenden Fehler:

"attempt to write a readonly database…"

Merkwürdig: Die Datei war von jedem les- und schreibbar.

Die Lösung: Der mysqli-Treiber will zwecks locking im Verzeichnis eine Flag-Datei anlegen, mit welcher signalisiert, dass diese Datei gerade schreibend benutzt wird. Also muss auch das Verzeichnis vom Webserver beschreibbar sein.

Ich hab das jetzt wie folgt gelöst:

<?php

if ( ! $pdo = PDOSQLite3Connect (
    SQLite3File,
    PDOReadOnly,
    E_USER_ERROR
) ) {
	exit;
}


function PDOSQLite3Connect ( $SQLite3File, $PDOReadOnly ) {

	if ( ! $PDOReadOnly ) {
		if ( ! is_writable( $SQLite3File ) ) {
			error_log( '(PDO): Datei "' . $SQLite3File . '/" muss beschreibbar sein.' );
			showErrorMsg();
			return false;
		}

		if ( ! is_writable( dirname( $SQLite3File ) ) ) {
			error_log( '(PDO): Verzeichnis "' . dirname( $SQLite3File ) . '" muss beschreibbar sein.' );
			showErrorMsg();
			return false;
		}
	}

	if ( ! $pdo = new PDO( 'sqlite:' . $SQLite3File ) ) {
		error_log( 'Datenbankverbindung zu "sqlite:' . SQLite3File . '" hat nicht funktioniert.' ); 
		showErrorMsg();
		return false;
	} else {
		return $pdo;
	}
}

showErrorMsg() zeigt ohne Optionen einen "allgemeinen" Server-Fehler an.

FRAGE:

Geht das eleganter?

Zweitens ein Tipp:

Bei Fummeln und testen bin ich über Folgendes gestolpert: In SQLITE gibt es kein TRUNCATE. Der oft gelesene Tipp, die Tabelle mit

DELETE FROM table;

zu löschen leert zwar die Tabelle, lässt aber den (letzten) Autoindex stehen.

Will man den auch löschen, dann geht das so:

DELETE FROM table;
DELETE FROM SQLITE_SEQUENCE WHERE name='table';
  1. Lieber Jörg,

    ich weiß nicht, ob ich Dir in Sachen "eleganter" wirklich helfen kann, jedoch habe ich Rückfragen zu Deinem Code, weil ich zwei Details nicht verstehe.

    if ( ! $pdo = PDOSQLite3Connect (
        SQLite3File,
        PDOReadOnly,
        E_USER_ERROR
    ) ) {
    	exit;
    }
    

    Du verwendest hier eine Konstante mit Namen E_USER_ERROR. Keine Ahnung, welcher Wert darin steht, vermutlich ein integer.

    function PDOSQLite3Connect ( $SQLite3File, $PDOReadOnly ) {
      ...
    }
    

    Hier wird diese Konstante nicht empfangen. Warum wird sie dann beim Aufruf mit übergeben? Und warum sollte sie das müssen? Sind Konstanten nicht superglobal, so dass man sich deren Übermittlung als Parameter sparen kann?

    Vielleicht ist das ja nur ein Überbleibsel von copy&paste.

    	if ( ! $pdo = new PDO( 'sqlite:' . $SQLite3File ) ) {
    		error_log( 'Datenbankverbindung zu "sqlite:' . SQLite3File . '" hat nicht funktioniert.' ); 
    		showErrorMsg();
    		return false;
    	} else {
    		return $pdo;
    	}
    }
    

    Wozu den else-Zweig? Warum nicht einfach den if-Zweig ohne else notieren und als letzte Anweisung in der Funktion das return $pdo?

    Ansonsten habe ich mit SQLite noch nie etwas zu tun gehabt. Meine DB-Kenntnisse beschränken sich auf MySQL/MariaDB.

    Liebe Grüße

    Felix Riesterer

    1. Hallo Felix,

      E_USER_ERROR

      Sie zu übergeben und nicht übernehmen ist ein Lapsus, ja. Kann passieren.

      Ob man nun

      if ($foo) {
         doSomething();
         return 42;
      }
      else
      {
         doSomethingElse();
         return 17;
      }
      

      schreibt oder

      if ($foo) {
         doSomething();
         return 42;
      }
      doSomethingElse();
      return 17;
      

      das halte ich für Geschmackssache. Aus meiner Sicht kann man beides machen, die Version ohne ELSE ist dann ausdrucksstärker, wenn der if eine Eingangsverifizierung macht und danach der größere Hauptteil kommt. Die Version mit ELSE drückt für mich aus, dass beide Teile in etwa gleich wichtig sind, UND sie drückt aus, dass hier definitiv Schluss ist.

      Rolf

      --
      sumpsi - posui - obstruxi
    2. Du verwendest hier eine Konstante mit Namen E_USER_ERROR. Keine Ahnung, welcher Wert darin steht, vermutlich ein integer.

      Nicht „vermutlich“. Quelltext meines Info-Tools.

      Aber Rolf hat recht, das ist ein hyperliquider Rest vom Copy & Paste.

      Sind Konstanten nicht superglobal, so dass man sich deren Übermittlung als Parameter sparen kann?

      Ursprünglich wollte ich den Wert entweder(sic!) vom E_USER_ERROR, E_USER_WARNING oder E_USER_NOTICE übermitteln und fand es sinnvoll (und ergo elegant) die lesbare und aussagekräftige Konstante zu notieren. Im konkreten Anwendungsfall wurde aber die ganze Übermittlung obsolet. Der Funktionsaufruf hier im Beitrag war die alte Version, die Funktion schon die bereinigte.

      Insofern fragst Du natürlich zu Recht, was die Konstante da sollte.

    3. Ansonsten habe ich mit SQLite noch nie etwas zu tun gehabt. Meine DB-Kenntnisse beschränken sich auf MySQL/MariaDB.

      Ich habe bei einem Test mal bemerkt, dass es wohl bei „einfachen Geschichten“ sehr schnell sein kann. Im Anwendungsfall geht es um Statistiken, die ich für meinen ServerSpeed-Test erstellen und auswerten will um nicht nur dröge Werte zu präsentieren, sondern einen Vergleich zu schaffen.

      Ansonsten wäre noch anzumerken, dass ich in meinem Linux immer mal auf sqlite stoße. Zum Beispiel im Firefox-Profil… Insofern scheint sich die Beschäftigung zu lohnen.

      1. Tach!

        Ansonsten habe ich mit SQLite noch nie etwas zu tun gehabt. Meine DB-Kenntnisse beschränken sich auf MySQL/MariaDB.

        Ich habe bei einem Test mal bemerkt, dass es wohl bei „einfachen Geschichten“ sehr schnell sein kann. [...]

        Ansonsten wäre noch anzumerken, dass ich in meinem Linux immer mal auf sqlite stoße. Zum Beispiel im Firefox-Profil… Insofern scheint sich die Beschäftigung zu lohnen.

        Vor allem lohnt sich eine Einsatzerwägung, wenn man darüber nachdenkt, ob eine ausgewachsene Datenbank zu viel für das Projekt sein und selbst geschriebene Dateien ausreichend scheinen. Bei Dateien stößt man dann schnell auf Gegebenheiten, für die man Lösungen braucht. Allem voran ist das der konkurrierende Zugriff auf Dateisystemebene, für den man sich mit File-Locking beschäftigen müsste. SQLite hat das bereits eingebaut, und man muss sich nur noch Gedanken um konkurrierende Zugriffe auf Datensatzebene machen. Möglichkeiten zur Strukturierung der Daten und deren Abfrage sind auch bereits vorhanden und müssen nicht neu erfunden werden.

        dedlfix.

        1. Vor allem lohnt sich eine Einsatzerwägung, wenn man darüber nachdenkt, ob eine ausgewachsene Datenbank zu viel für das Projekt sein und selbst geschriebene Dateien ausreichend scheinen. Bei Dateien stößt man dann schnell auf Gegebenheiten, für die man Lösungen braucht. Allem voran ist das der konkurrierende Zugriff auf Dateisystemebene, für den man sich mit File-Locking beschäftigen müsste. SQLite hat das bereits eingebaut, und man muss sich nur noch Gedanken um konkurrierende Zugriffe auf Datensatzebene machen. Möglichkeiten zur Strukturierung der Daten und deren Abfrage sind auch bereits vorhanden und müssen nicht neu erfunden werden.

          100% Zustimmung von mir.

  2. Hallo Raketenleichtmatrose,

    tja, was heißt eleganter. Die Prüfungen müssen ja stattfinden.

    Wäre dies hier für Dich eleganter? Hab's jetzt nicht wirklich durchgetestet 😉

    function PDOSQLite3Connect ( $SQLite3File, $PDOReadOnly ) {
    
      try
      {
        ensure( PDOReadOnly || is_writable( $SQLite3File ),
          '(PDO): Datei "' . $SQLite3File - '" muss beschreibbar sein.' );
        ensure( PDOReadOnly || is_writable( dirname( $SQLite3File ) ),
          '(PDO): Verzeichnis "' . dirname( $SQLite3File ) - '" muss beschreibbar sein.' );
    
        ensure( $pdo = new PDO( 'sqlite:' . $SQLite3File,
          'Datenbankverbindung zu "sqlite:' . SQLite3File . '" hat nicht funktioniert.');
        return $pdo;
      }
      catch (AssertionError $err)
      {
        errorLog( $err->getMessage() );
        showErrorMsg();
      }
    }
    
    function ensure( $condition, $message ) {
       if ($condition)
          return;
    
       throw new AssertionError($message);
    }
    

    Rolf

    --
    sumpsi - posui - obstruxi
    1. tja, was heißt eleganter. Die Prüfungen müssen ja stattfinden.

      Ich dachte mehr an: PDO-Klasse erweitern ... Oder das PDO-Objekt bzw. dessen Erstellung in einem eigenen Objekt wrappen und die Prüfungen da hineinbauen.

      1. Hallo Jörg,

        könnte man auch überlegen. Die PDO Klasse ist nicht sealed final und man kann sie beerben, z.B. durch eine Klasse RSDO (Rocket SQLite Data Objects), die sich ausschließlich um PDO für SQLite kümmert und entsprechende Checks enthält.

        Darin könntest Du den Konstruktor erweitern und bei Verletzung der Vorbedingungen ein paar Exceptions durch die Gegend schießen.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hm. So könnte es gehen ...

          <?php
          class RPDO extends PDO {
          
          	protected $arErrors = [];
          	protected $pdo = false;
          	protected $errorTypes = [
          		0,
          		E_USER_NOTICE,
          		E_USER_WARNING,
          		E_USER_ERROR
          	];
          
          	function __construct ( $string, $errType = E_USER_ERROR ) {
          		
          		if ( ! in_array( $errType, $this-> errorTypes ) ) {
          			trigger_error( '$errType  has to be ' . implode (' or ', $this ->errorTypes ), E_USER_ERROR );	
          		}		
          		
          		if ( 0 === strpos( $string, 'sqlite:') ) {
          			
          			$filename = trim( substr ( $string, 7, strlen( $string ) ) );
          			$dirname  = dirname( $filename );
          			
          			if ( '' == $dirname ) {
          				$dirname = './';
          			}
          			
          			if ( ! is_writable ( $dirname ) ) {
          				$eMsg = 'The directory "' . $dirname . ' has to be writable.';
          				$this -> arErrors[] = $eMsg;
          			} 
          
          			if ( ! is_file( $filename ) ) {
          				$eMsg = 'the file "' . $filename . '" not exits.';
          				$this -> arErrors[] = $eMsg;
          			} else {
          					if ( ! is_readable( $filename ) ) {
          					$eMsg = 'the file "' . $filename . '" is not readable';
          					$this -> arErrors[] = $eMsg;	
          				}
          				if ( ! is_writable( $filename ) ) {
          					$eMsg = 'the file "' . $filename . '" is not writable';
          					$this -> arErrors[] = $eMsg;
          				}
          			}
          
                      if ( count( $this -> arErrors ) ) {
          				if ( 0 != $errType ) {
          					trigger_error( implode( ' and ', $this -> arErrors ) , $errType );
          				}
          				return false;
          			}
          			
          			$this -> pdo = new PDO ( $string );
          		}
          		return ( $this->pdo );
          	}
          	
          	function hasErrors() {
          		if ( count( $this -> arErrors ) ) { 
          			return true;
          		} else {
          			return false;
          		}
          	}	
          	
          	function getErrors() {
          		if ( $this -> hasErrors ) {
          			return $this -> arErrors;
          		} else {
          			return false;
          		}
          	}
          	
          	function getPDO() {
          		return ( $this -> pdo ) ;
          	}	
          }
          
          
          /* Usage & Tests:
          #$rpdo = new RPDO ( 'sqlite: values.sqlite3', 0 );
          #$rpdo = new RPDO ( 'sqlite: values.sqlite3', E_USER_NOTICE );
          #$rpdo = new RPDO ( 'sqlite: values.sqlite3', E_USER_WARNING );
          $rpdo = new RPDO ( 'sqlite: values.sqlite3', E_USER_ERROR );
          if (! $rpdo-> hasErrors() ) {
          	$pdo  = $rpdo -> getPDO();
          	var_dump($pdo);
          }
          var_dump( $rpdo );
          #*/
          
          1. Hallo Jörg,

            nein, so geht das nicht. Es ist falsch, ein inneres $pdo Property zu haben. Du schreibst eine Subklasse, keinen Dekorierer, deswegen ist $this dein PDO Objekt. Der return-Wert eines Konstruktors wird ignoriert. D.h. du musst parent::__construct() verwenden, nicht new PDO().

            Ich sehe zwar gerade nicht, wo das in der PHP Doku steht, aber ich habe es ausprobiert und diese Info bei SO gefunden. PHP ist nicht JavaScript, wo der Rückgabewert der Konstruktorfunktion beachtet wird. PHPs __construct gibt immer $this zurück.

            Meine weiteren Einwände sind meine Meinung und nicht maßgeblich ;)

            Ich hätte eine spezifische SQLite-Subklasse für PDO gemacht. Der Konstruktor bekommt den Teil des PDO dsn-parameters, der hinter dem Doppelpunkt steht. Das schließt dann zwar auch den uri: Metadriver aus, aber der widersetzt sich deinen Plausis ohnehin.

            hasErrors/getErrors würde ich auch nicht machen. PDO::__construct wirft eine Exception, wenn was schiefgeht. Bleibe idiomatisch[1].

            Rolf

            --
            sumpsi - posui - obstruxi

            1. Look ma, you're really important here! ↩︎

            1. D.h. du musst parent::__construct() verwenden, nicht new PDO().

              DAS war der entscheidende Hinweis!

              <?php
              class RPDO extends PDO {
              
              	protected $arErrors = [];
              	protected $errorTypes = [
              		0,
              		E_USER_NOTICE,
              		E_USER_WARNING,
              		E_USER_ERROR
              	];
              
              	function __construct ( $string, $errType=E_USER_ERROR ) {
              		
              		if ( ! in_array( $errType, $this-> errorTypes ) ) {
              			trigger_error( '$errType  has to be ' . implode (' or ', $this ->errorTypes ), E_USER_ERROR );	
              		}		
              		
              		if ( 0 === strpos( $string, 'sqlite:') ) {
              			
              			$filename = trim( substr ( $string, 7, strlen( $string ) ) );
              			$dirname  = dirname( $filename );
              			
              			if ( '' == $dirname ) {
              				$dirname = './';
              			}
              			
              			if ( ! is_writable ( $dirname ) ) {
              				$eMsg = 'The directory "' . $dirname . ' has to be writable.';
              				$this -> arErrors[] = $eMsg;
              			} 
              
              			if ( ! is_file( $filename ) ) {
              				$eMsg = 'the file "' . $filename . '" not exits.';
              				$this -> arErrors[] = $eMsg;
              			} else {
              					if ( ! is_readable( $filename ) ) {
              					$eMsg = 'the file "' . $filename . '" is not readable';
              					$this -> arErrors[] = $eMsg;	
              				}
              				if ( ! is_writable( $filename ) ) {
              					$eMsg = 'the file "' . $filename . '" is not writable';
              					$this -> arErrors[] = $eMsg;
              				}
              			}
              
                          
                          if ( count( $this -> arErrors ) ) {
              				if ( 0 != $errType ) {
              					trigger_error( implode( ' and ', $this -> arErrors ) , $errType );
              				}
              			}
              			
              			try {
              				parent::__construct( 'sqlite:' . $filename );
              			} catch( PDOException $e ) {
              				trigger_error( $e -> __toString(), E_USER_ERROR );
              			}
              		}
              	}
              }
              
              
              /** Tests: **/
              
              #/*
              $pdo = new RPDO ( 'sqlite: values.sqlite3', E_USER_NOTICE );
              #$pdo = new RPDO ( 'sqlite:readonly.sqlite3', E_USER_NOTICE );
              #$pdo = new RPDO ( 'sqlite:readonly.sqlite3', E_USER_ERROR );
              $pdo = new RPDO ( 'sqlite:leer', E_USER_ERROR );
              $sql = 'SELECT id, timestamp, url_effective FROM speed LIMIT 2';
              try {
              	$stmt = $pdo->prepare( $sql );
              	if ( $stmt ) {
              		$stmt -> execute();
              		while  ( $result = $stmt -> fetch( PDO::FETCH_ASSOC ) ) {
              			print_r( $result );
              		}
              	} else {
              		trigger_error( 'SQL-Error: ' . ( $pdo->errorInfo() )[2] . ' in "' . $sql .'"', E_USER_ERROR );
              	}
              } catch ( PDOException $e ) {
                  trigger_error( $e -> __toString(), E_USER_ERROR );
              }
              # */
              

              hasErrors/getErrors würde ich auch nicht machen.

              [x] Deleted, wird nicht gebraucht.

  3. Das Problem kommt mir bekannt vor. Das liegt an dem Lock-Mechanismus für SQLite. Hab mich aber noch nicht näher damit befasst.

    MFG

    1. Das Problem kommt mir bekannt vor.

      Klar. Du kennst ja sicher auch noch DBase und andere Ansätze für den Betrieb von Datenbanken unter MS-DOS, also auf Systemen, die immer nur ein Programm ausführen und deshalb keine Dienste anbieten können. sqlite läuft genau so wie einst das gute alte DBase als Programm im Userspace und muss also muss das Locken der Datei irgendwie über das Dateisystem funktionieren.

      Dafür ist es bei kleinen Aufgaben halt sehr schnell.

      1. Du kennst ja sicher auch noch DBase und andere Ansätze..

        Ja sicher doch, hab lange genug mit der BDE programmiert, zuerst in einer dBase-Umgebung später mit Delphi.

        Dafür ist es bei kleinen Aufgaben halt sehr schnell.

        Das ist aber nicht SQLite spezifisch sondern grundsätzlich so. Wobei es natürlich auch vom Algorithmus abhängt und wie dieser implementiert ist.

        Auf jeden Fall war es schon immer so, daß eine 5-MB-Datei schneller in den RAM gelesen als eine DB-Verbindung hergestellt ist. Und zum Speichern meiner Objekte brauche ich kein SQLite.

        MFG

        1. Und zum Speichern meiner Objekte brauche ich kein SQLite.

          Guggst Du erschöpfende Antwort von Dedlfix.

          1. Und zum Speichern meiner Objekte brauche ich kein SQLite.

            Guggst Du erschöpfende Antwort von Dedlfix.

            Im Zeitalter abstrakter Data-Access-Layer und objektorientierter Datenhaltung betrachte ich das als obsolet. Und dieses Zeitalter begann bei mir vor mehr als 20 Jahren!

            MFG

      2. also muss das Locken der Datei irgendwie über das Dateisystem funktionieren.

        Da kannste mal sehen wie antiquiert SQLite tickt. Außer daß man da eine proprietäre SQL draufgesetzt hat ist das auch nichts anderes als dBase, BDE oder Berkeleydatenbanken. Wobei Letztere schonmal einen Fortschritt darstellten und selbstverständlich auch schon Nonblocking, mandatory und advisory Locking implementierten.

        MFG

        1. Hallo pl,

          „gibt es schon lange“ ≠ „antiquiert“. Ohne einen Dienst, der sich um das Locking kümmert, muss man Betriebssystemmittel anwenden.

          Welche modernere Methode würdest Du vorschlagen, bei gleichbleibendem Mini-Footprint für die DB?

          Rolf

          --
          sumpsi - posui - obstruxi
          1. hi

            „gibt es schon lange“ ≠ „antiquiert“. Ohne einen Dienst, der sich um das Locking kümmert, muss man Betriebssystemmittel anwenden.

            Nein. Da gibt es Bibliotheken die das vom OS entkoppeln, in Perl ist das Fcntl und auch PHP nutzt dieselben c-Libraries.

            Welche modernere Methode würdest Du vorschlagen, bei gleichbleibendem Mini-Footprint für die DB?

            Modern finde ich Data-Access-Layer die austauschbar sind und zwar so daß man bei einem Umzug auf einen anderen Speicherort am Code der Anwenduing nichts ändern muss.

            MFG

            1. Modern finde ich Data-Access-Layer die austauschbar sind und zwar so daß man bei einem Umzug auf einen anderen Speicherort am Code der Anwenduing nichts ändern muss.

              MFG

              Und bei einer Änderung an der Datenstruktur in der Anwendung am Data-Access-Layer nichts ändern muss.

            2. Hallo pl,

              ich komm gleich mit der Heißwasserbrause, um die Seife zu entfernen, mit der Du wegflutschen willst.

              Wir reden hier nicht vom Interface Application -> Data Layer, sondern von der konkreten Implementierung des Layers für SQLite.

              Und was hat der Einsatz einer Library mit der Nutzung eines bestimmten Betriebssystem-Mechanismus zu tun? Wie sorgt denn Fcntl dafür, dass zwei Prozesse nicht gleichzeitig auf eine Datei zugreifen können? Durch einen proprietären Mechanismus, der nur für Nutzer von Fcntl wirksam ist? Das wäre fatal - wenn ich den Zugriff auf eine Ressource serialisieren will, brauche ich eine zentrale Instanz, die die Serialisierung kontrolliert und die nicht umgangen werden kann. Das ist entweder ein Dienst (Daemon), ohne den kein Zugriff möglich ist und der die Sperre in-memory übernimmt, oder das Betriebssystem.

              Der übliche Serialisierungsmechanismus für Dateien besteht aus File Locks. Auch Fcntl wird die nutzen.

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Wie sorgt denn Fcntl dafür, dass zwei Prozesse nicht gleichzeitig auf eine Datei zugreifen können?

                Indem es die darunterliegenden c-Libraries nutzt. Das ermöglicht dem Anwender, plattformunabhängigen Code zu schreiben und so setzt Fcntl bspw. spontan entweder ein advisory-Lock oder ein mandatory-Lock, je nachdem was das darunterliegende OS ermöglicht. Siehe mein Artikel !

                1. Dieser Beitrag wurde gelöscht: Beleidigung
                2. Hallo pl,

                  so setzt Fcntl bspw. spontan entweder ein advisory-Lock oder ein mandatory-Lock

                  File Locks? Da kannste mal sehen wie antiquiert Fcntl tickt.

                  SCNR
                  Rolf

                  --
                  sumpsi - posui - obstruxi
              2. Das wäre fatal - wenn ich den Zugriff auf eine Ressource serialisieren will, brauche ich eine zentrale Instanz, die die Serialisierung kontrolliert und die nicht umgangen werden kann.

                Volle Zustimmung, man spricht bei nebenläufigen Systemen übrigens i.d.R. von "Synchronisierung" und nicht von "Serialisierung".

                1. Hallo 1unitedpower,

                  nein, ich meine tatsächlich serialisieren im Sinne von "nacheinander ausführen". Der Begriff ist nicht eindeutig. Guckst Du hier, Punkte 1+2.

                  Synchronisieren findet einen Level höher statt und bezieht sich auf andere Objekte. Wenn ich nebenläufige Vorgänge A, B und C habe, und A erst weiterlaufen darf, wenn B und C fertig sind, dann muss ich die Tasks A, B und C synchronisieren (= den Zeitablauf abstimmen).

                  Das kann ich auf verschiedene Arten tun, bspw. ein Zähler oder eine Message-Queue. Die Zugriffe auf das Synchronisierungswerkzeug Zähler oder Queue muss ich serialisieren (= nacheinander ausführen), um das Werkzeug nicht zu beschädigen.

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                  1. Hallo Rolf,

                    jetzt hab ich fast 20 Minuten an einer Antwort geschrieben, nur um sie dann wegzuwerfen. Du warst schneller 😉

                    Freundliche Grüße,
                    Christian Kruse

                    1. Hallo Christian,

                      warum sollte ich der einzige sein dem es regelmäßig so geht 😂

                      Rolf

                      --
                      sumpsi - posui - obstruxi
                  2. Nachtrag

                    ok, wenn ich in der de Wikipedia stöbere, dann benutzen die dort den Begriff Sequentialisierung. Aber den habe ich noch nie gehört. Vielleicht ist mein Mindset dafür zu denglisch.

                    Rolf

                    --
                    sumpsi - posui - obstruxi
                    1. ok, wenn ich in der de Wikipedia stöbere, dann benutzen die dort den Begriff Sequentialisierung. Aber den habe ich noch nie gehört. Vielleicht ist mein Mindset dafür zu denglisch.

                      Meinst du vielleicht Scheduling? Also die Festlegung der Reihenfolge, in der Zugriffe auf geteilte Ressourcen erolgen?

                  3. nein, ich meine tatsächlich serialisieren im Sinne von "nacheinander ausführen". Der Begriff ist nicht eindeutig. Guckst Du hier, Punkte 1+2.

                    Ja, okay, zumindest in meiner kleinen Filterblase (ich arbeite derzeit an einem Framework für die Verifikation verteilter Systeme) ist "Synchroniserung" der dafür etablierte Terminus, "Serialisierung" habe ich noch nicht gelesen. Aber das mag außerhalb meine Filterblase durchaus anders sein, außedem verstehe ich ja was du meinst, und will also keine Erbsen zählen.