Version 2.8.5. - Bestellungen "verschwinden"

Antwort erstellen

Bestätigungscode
Gib den Code genau so ein, wie du ihn siehst; Groß- und Kleinschreibung wird nicht unterschieden.
Smileys
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :arrow: :| :mrgreen: :geek: :ugeek:

BBCode ist eingeschaltet
[img] ist eingeschaltet
[url] ist eingeschaltet
Smileys sind eingeschaltet

Die letzten Beiträge des Themas
   

Ansicht erweitern Die letzten Beiträge des Themas: Version 2.8.5. - Bestellungen "verschwinden"

Re: Version 2.8.5. - Bestellungen "verschwinden"

von pichel » So 11. Aug 2024, 23:09

Hallo allerseits,

ich habe gerade eine Version 2.8.8 herausgebracht, in der ich das Transaktionshandling überarbeitet habe. Es sollte jetzt zuverlässiger funktionieren, aber ich befürchte, dass darunter die Performance ein wenig leiden könnte.

Jedenfalls würde ich mich sehr über Feedback freuen, wie sich die Version verhält, wenn viele gleichzeitige Zugriffe passieren, d.h. beim Einsatz bei großen Festen. Gibt es zwischendurch Hänger, Ausfälle o.ä.? Der Praxisfall lässt sich halt nicht so gut testen.

Viele Grüße,

Stefan

Re: Version 2.8.5. - Bestellungen "verschwinden"

von pichel » Fr 9. Aug 2024, 00:20

Hallo Lutz, hallo in die Runde,

einen großen Dank an Lutz, der sich in den Code eingearbeitet hat und die Fehlerursache wahrscheinlich gefunden hat. Ich habe einen Patch angehängt, der das Problem hoffentlich lösen sollte. Meine Lösung sieht so aus, dass ich die Transaktion für das Hinzufügen und Entfernen von Artikeln in/aus der Db mit dem Serializable-Isolationslevel starte. Damit können keine ID-Konflikte bei dieser Operation mehr entstehen, aber die Performance leidet darunter.

Wer mag, kann das gerne auf einer 2.8.7 ausprobieren, indem er die zip-Datei in den php-Ordner entpackt. Es sind drei Dateien (commonutils.php und queuecontent.php in den php-Ordner, operations.php in den Unterordner php/utilities). Wer also mag, kann testen, ob ich damit den Bug gelöst habe und ob die Performance darunter sehr leidet.

Ich möchte darauf hinweisen, dass der gleiche Fehler möglicherweise auch beim Kassieren passieren kann, d.h. der Patch in diesem Status wahrscheinlich noch nicht für alle umsatzrelevanten Aktionen hilft.

Gruß,

Stefan
Dateianhänge
patch-transaction.zip
(35.35 KiB) 283-mal heruntergeladen

Re: Version 2.8.5. - Bestellungen "verschwinden"

von irrsinn.de » Do 8. Aug 2024, 11:43

Hallo Daniel,

Das Problem tritt NUR bei aktiver TSE-Signierung auf. Hatte ich das oben vergessen zu erwähnen? Wir hatten die TSE testweise mal abgeschaltet und konnten es nicht nachstellen.

Nachtrag: Ich hatte einen langen Beitrag geschrieben, in dem ich auf den Code eingegangen bin. Den hat Stefan noch nicht freigeschaltet. Auf den bezog ich mich mit "Hatte ich das oben vergessen zu erwähnen?" ;)

Re: Version 2.8.5. - Bestellungen "verschwinden"

von daniel » Mi 7. Aug 2024, 21:13

Hallo Lutz,
Hallo Stefan,

ich habe es bei mir auf einem System getestet: allerdings "nur" mit Ordersprinter 2.8.1 und ohne TSE

mit dem Vorgehen: "2 Handys, Buchung jeweils 1 Artikel auf einen Tisch (wobei sowohl der Artikel, als auch der Tisch bei jedem Handy ein anderer ist - ich habe auch unterschiedliche Benutzer verwendet) - dann habe ich annähernd zeitgleich auf Arbeitsbon (im 1. Versuch) oder auf Kasse (im 2. Versuch) geklickt.

dabei sind bei mir leider oder zum Glück KEINE Bestellungen verschwunden.

Viele Grüße Daniel

Re: Version 2.8.5. - Bestellungen "verschwinden"

von irrsinn.de » Mi 7. Aug 2024, 17:18

Hallo Stefan,

wir haben uns jetzt mal den Aufwand gemacht und sind in den Kaninchenbau hinabgestiegen und haben folgendes vorgefunden:

Das Problem findet seinen Ursprung wenn die TSE aktiv ist und Buchungen signiert.
Also fangen wir an in der Methode addProductListToQueueCore

Um dem Problem auf die Spur zu kommen ist es wichtig, das wir verstehen das in der Methode addProductListToQueueCore die Datenbank Transaction gestartet wird:

Code: Alles auswählen

public function addProductListToQueueCore($pdo,$ordertime,$theTableid,$prods,$doPrint,$payprinttype,$userid,$quickcash, $order = null,$orderOption="") {

                if (intval($theTableid) == 0) {
                        $theTableid = null; // togo room
                }

                if (!is_null($order)) {
                      $order->setCreatorid($userid);
                }
                $printAndQueueJobs = CommonUtils::getConfigValue($pdo, "printandqueuejobs", 0);
                if ($printAndQueueJobs == 1) {
                        $doPrint = 1;
                }

                $pdo->beginTransaction();
Siehe hier $pdo->beginnTransaction. Nun finden im Code eine Reihe vorbereitender Maßnahmen statt. Ist die TSE aktiv, so wird dann innerhalb der Methode die Methode signAtTSE gecalled. Der Methode wird dann das PDO-Objekt mit der gestarteten Transaktion übergeben. Die Methode signAtTSE reicht ihrerseits dann die Daten nach erfolgreicher Signierung weiter an die Methode createOperations der Klasse Operations.

Und hier wird es dann interessant:
Wir haben hier in der Klasse das PDO-Objekt mit der laufenden Transaktion rein bekommen. Um die Daten in die Table os_operations schreiben zu können werden vorher zwei neue IDs selbst kreiert. Das das schief gehen kann findet sich auch im Code.

Code: Alles auswählen

           // In parallel transactions and with transaction isolatoon level REPEATABLE READ it may be possible that the max id is already set by another transaction.
            // Therefore run this in a try catch block just in case of a deadlock and increment the maxid in catch
            // In a very very unikely case of race condition still the bonid can be created multiple times, but the unique primary key id is evidence that there is no
            // intention in creating an invalid operation. Therefore also this comment is left in this source code!
Und beim Versuch die Daten zu schreiben wird dann eine Exception gefangen, wenn es die ID schon geben sollte.

Code: Alles auswählen

                      try {
                                if ($maxtries == 4) {
                                        $signtxt = $signtxt_ascii;
                                        error_log("Using from now on the ascii version of the signtxt to store in operations table");
                                }
                                CommonUtils::execSql($pdo, $sql, array($maxid+1,$range,$maxbonid+1,$opType,$table,$logtime,$trans, $sigcounter, $tseSignature, $pubkeyRef, $sigalgRef, $serialNoRef,$certificateRef, $signtxt, $tseerror, $terminalEntryId));
                                $ok = true;
                        } catch (Exception $ex) {
                                $maxid++;
                                $attempt++;
                                $maxtries--;
                                sleep(1);
                        }
Aber diese Exception wird niemals fliegen, da wir uns in einer Transaktion befinden und die IDs selbst erstellt haben. Die Datenbank Transaktion hat keine Kenntnis von den IDs und glaubt und. Also werden hier bei einer zeitgleichen Transaktion eine die gleiche maxid und maxbonid.

Das fällt aber erst beim finalen commit auf und die Daten werden nicht in die Datenbank geschrieben.

--------------------

Lieber Stefan,

konnten wir Dir damit helfen? Sollen wir versuchen das selbst zu lösen und Dir das dann in die Hand drücken?

Re: Version 2.8.5. - Bestellungen "verschwinden"

von Skifan » Mi 7. Aug 2024, 16:40

Hallo in die Runde,
wie oben von mir beschrieben, hatten wir das Problem auch ab und zu. Leider kann ich das Problem, wie beschrieben zu Hause, nicht mehr reproduzieren. Evtl. liegt es daran, dass wir bei unserer Veranstaltung einen PC mit einer älteren PHP Version hatten.
Ich habe heute XAMPP mit PHP Version 8.2.12 installiert, die php.ini wie beschrieben angepasst, Ordersprinter komplett neu aufgesetzt und die config Datei von unserer Veranstaltung importiert.
Dann habe ich versucht zeitgleich 2 Produkte zu bestellen. Es kommt jeder Bon an.

Re: Version 2.8.5. - Bestellungen "verschwinden"

von irrsinn.de » Mi 7. Aug 2024, 10:25

Hallo Stefan,

nein, daran haben wir nichts geändert das ist nach wie vor die Installation aus seinem Script. Das Problem ist inzwischen auf zwei Kassen beliebig reproduzierbar. Du nimmst einfach 2 Tablets, klickst auf 2 unterschiedlichen Tischen, jeweils ein Produkt und versucht annähernd zeitgleich auf Arbeitsbon zu drücken.


rn_image_picker_lib_temp_3a735a8b-b5b5-48d5-b9ad-95d91844b050.jpg
rn_image_picker_lib_temp_3a735a8b-b5b5-48d5-b9ad-95d91844b050.jpg (84.89 KiB) 4800 mal betrachtet

Re: Version 2.8.5. - Bestellungen "verschwinden"

von pichel » Di 6. Aug 2024, 23:09

Hallo Lutz,

kann es sein, dass du an der InnoDB-Konfiguration gedreht hast, um eine vermeintliche bessere Performance zu erreichen? Interessant wäre zum Beispiel, welchen Isolation-Level du als Standard eingestellt hast. Das bekommst du mit diesem Kommando raus:

Code: Alles auswählen

select @@global.tx_isolation, @@session.tx_isolation;
Das sollte mindestens auf REPEATABLE-READ stehen! "Read Uncommitted" und "Read Committed" reichen nicht aus, "Serializable" würde alles sehr verlangsamen und verwende ich deswegen explizit nur an einer Stelle!

Wenn es beispielsweise auf "Read (un)committed" steht, würde es das von dir beobachtete Verhalten erklären, wäre aber ein ziemlicher Fehler beim grundsätzlichen Setup des Systems!

Das sleep(rand(1-5)) (du meinst bestimmt "1,5" statt "1-5") am Anfang der Methode addProductListToQueueCore() würde das Problem auch nicht lösen, denn damit hast du zwar JEDE Abarbeitung von Bestellungen um ein paar Sekunden verlangsamt (da es ein synchroner REST-Call ist, frierst du das UI sogar beim sleep ein), aber Kollisionen können trotzdem passieren, nur eben nicht mehr, wenn beide Parteien absolut zeitgleich eine Bestellung an den Server schicken.

Gruß,

Stefan

Re: Version 2.8.5. - Bestellungen "verschwinden"

von irrsinn.de » Di 6. Aug 2024, 00:04

Hallo Stefan,

das Problem liegt in Verarbeitung der PDO Transaction in der Methode "addProductListToQueueCore" in der queuecontent.php
Wenn zwei zeitgleiche Requests zur Anlage einer Bestellung kommen, dann fällt einer auf die Nase, weil die Transaktion nicht ausgeführt
wird. Trotz der Tatsache, dass das "$pdo->commit" die Ausführung mit true quittiert, werden die Daten der Transaktion nicht persistiert.
Die sind einfach weg. Dieses liegt offenbar an der Dauer der Transaction.

Wir haben uns nun mit einem Workaround geholfen, dass wir vor dem Return "OK" nochmal checken ob die QueueID der Transaction auch
wirklich in der Datenbank steht. Falls nicht, dann bekommt der User einen "Error" angezeigt und muss nochmal auf Arbeitsbon klicken.
Ein Dirty-Hack ist auch, wenn man direkt beim Start der Methode die Ausführung des Codes willkürlich um 1-5 Sekunden verzögert, so das eine zeitgleiche Ausführung fast immer vermieden wird.

Code: Alles auswählen

public function addProductListToQueueCore(...){

  sleep(rand(1-5));
In diesem Bereich haben wir zum einen keine Anpassungen vorgenommen und zum anderen entsteht bei dem oben Beschriebenen Bug auch keine Fehlermeldung in den Apache Logs.

Re: Version 2.8.5. - Bestellungen "verschwinden"

von pichel » So 4. Aug 2024, 22:25

Hallo,

ich kann den Fehler in meiner Umgebung trotz vieler Versuche nicht reproduzieren. Aber es wäre schön, wenn ich ein Logfile des Webservers (error_log) bekäme mit Angabe, wann der Fehler aufgetreten ist, damit ich dann konkret das Log zu diesem Zeitpunkt analysieren kann. Allerdings muss es ein Log von einem Originalsystem sein, Fehler in vom Anwender angepassten Source-Code werde ich nicht suchen.

Gruß,

Stefan

Nach oben