Oxid shop verwendet keine DB transaction? wie sicher ist es dann mit z.B. Lagerbestand usw. bei stark besuchten shops?

Hallo zusammen, schraube fleißig an Synchronization von meinem Shop mit externen Platformen wie Amazon, da ist für mich wichtig, dass mein Lagerbestand immer gleich bleibt bei allen (Shop, Amazon usw.)

Dabei habe ich dann den Bestellungsvorgang von oxid studiert und stelle fest, dass oxid hier keine Transaction auf DB Ebene verwendet, um sicherzustellen dass man den Lagerbestand konsistent liest und dann ändert (also blocking read plus transaction). Für kleine Shops mag es ja ok sein, aber wenn man einen stark besuchten Shop hat, es kann schon durchaus vorkommen, dass zwei Kunden gleichzeitig dasselbe Produkt bestellen und es kommt zu falschem Lagerbestand? Vielleicht habe ich was übersehen, aber ohne DB transaction, weiss ich nicht, wie man solches Problem überhaupt lösen könnte…

Also hat jemand eine Idee, ist das Problem anders gelöst von oxid oder man muss sich damit abfinden, dass es doch zu Fehler kommen kann?

Viele Grüße,
Lin

Amazon will aber nicht, dass dein Lagerbestand alle 5 Sekunden synchronisiert wird.
Sie sagen selbst, dass es bis zu 6 Stunden dauern kann, bis deine Update-Requests bearbeitet wurden.

Außerdem ist der Lagerbestand bei stark frequentierte Shops, sofern dort Lagerverwaltung überhaupt aktiv ist, nur ein Shapshot aus der WaWi, der ebenfalls nachts oder ggf. alle 6-12 Stunden gemacht wird. Zumal die WaWi bzw ein ERP dort das Master-System ist und die Lagerbestände liefert, weil nur es dem tatsächlichen Lagerbestand am nächsten sein kann.

Die Wahrscheinlichkeit, dass dein Server von einer Flut zerstört und der ITler vom Hai gebissen wird, ist höher als, dass es zu dem erwähnten theoretischen Problem kommen kann.

Hi Vanilla Thunder, danke für die schnelle Antwort. Wegen 6 Stunden Amazon, ich lese da nur die Bestellungen, damit ich mein eigenen Lagerstand aktualisiert, also ist für mich nicht das größste Problem hier.

Du hast Recht dass für Enterprise Anwendungen, die Lagerbestand ist meist ein Snapshot, ich aber für meine Anwendung den Bestand immer realtime pflegen möchte und sogar muss, daher meine originelle Frage. Mir ist auch bewusst dass die Chance gering wäre, aber denke so gering ist es vielleicht auch nicht - für Onlineshops zählt jeder Kunde - ich möchte nur das Ereignis vermeiden, dass man mehr als Lagerbestand verkauft - es gibt dann Ärger mit Kunden und man verliert eventuell künftige Geschäfte.

Also wenn ich es richtig verstanden habe, es kann (theoretisch) zu Fehlern, es bestätigt dann meine Vermutung. Ich persönlich würde in meine eigene Skript ein Blocking read verwenden, um so was zu vermeiden. Ist ein paar zeilen code mehr, nimm aber einen Stein am Herz weg :wink:

VG, Lin

Die Ware verschwindet ja nicht bei der Bestellung vom Lager
Erst wenn das Geld eingegangen ist und die Ware auch tatsächlich verpackt wurde. Und bevor das Passiert, könnte der Kunde sich umentscheiden, aber das Geld erst 1 Woche später überweisen, oder in der Notiz geschrieben haben “bitte erst in 10 Tagen schicken, bin im Urlaub” oder die Bestellung stornieren. Und 5 andere Kunden sind deswegen auf der Strecke liegen geblieben, weil der Lagerbestand theoretisch weg war, obwohl in 2 Tagen eh Wareneingang gewesen wäre.

Aber zurück zum Thema: ob es tatsächlich zu falschem Lagerbestand kommen kann, weiß ich nicht.
Aber die reine Update-Query ist sehr anfällig für sowas:
http://docu.oxid-esales.com/CE/sourcecodedocumentation/4.9.8/classox_article.html#ad18359639560ac6d75d2e54b418d262c
Um solche Fehler vorzubeugen, darf man keine Werte zwischenspeichern.
Das müsste dann etwa so gehen:

update oxarticles set oxstock = oxstock - 5 where ...

anstatt den neuen Bestand aus einem vorher aus der DB geladenen Wert auszurechnen und die Update Query mit einem festen neuen Lagerbestand zu versehen.
Ich weiß auch nicht, ob dir Transactions hier helfen, da die Artikel zu einem bestimmten Zeitpunkt aus der DB geladen werden und dann mit den gespeicherten Werten gerechnet wird, bis die Lagerbestände irgendwann später aktualisiert werden. Dann müsstest du unter Umständen mit recht langen Datenbank Locks rechnen. (denke ich, ich hab mich noch nie wirklich gründlich damit beschäftigt)

Wenn es dich wirklich interessiert, könntest du vielleicht in der dev-general Mailingliste mal nachfragen. Dort gibts mehr Entwickler, die mit stark besuchten Shops arbeiten. Ich hab auch gehört, dass z.B: SysEleven irgendwelche eigenen High-Performance Patches für solche Shops hat.

Danke Vanilla Thunder, dein Query String ist eine alternative, wenn der tatsächliche Lagerbestand nicht relevant ist. Ich brauche es aber um zu prüfen, z.B. wenn es 0 ist, dass müssen alle Platformen das Produkt offline stellen.

Nach meiner Forschung bei mysql es müsste so gehen:

  1. Mache zuerst eine “locking read”, Referenz: http://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html
  2. reduziert den Bestand und update
    3)commit transaction

So müsste dann auf DB Ebene gehen. Solange es auf InnoDB Tables angewendet, Performance müsste ja gehen, da nur row-locking.

Danke für den Tipp mit der Mailinglist, ich teste zuerst mal meine Lösung und dann frage mal dort ob jemand die gleiche Sorge wegen Transaction haben wie ich :smiley:

LG, Lin

[QUOTE=fireincairo;180532]
Danke für den Tipp mit der Mailinglist, ich teste zuerst mal meine Lösung und dann frage mal dort ob jemand die gleiche Sorge wegen Transaction haben wie ich :smiley:

LG, Lin[/QUOTE]

Deine Sorge ist berechtigt. Wir haben bei Aktionsverkäufen erhebliche Probleme, die allesamt auf die fehlende Transaktionsfähigkeit von OXID zurückzuführen ist:

  • Kaputte Lagerbestände, wenn ein Artikel oft in kurzer Zeit verkauft wird [1]
  • Artikel werden mehrfach in eine Bestellung hinzugefügt, wenn Kunden es schaffen, denselben Request 2x abzusetzen, bevor die Daten in die Datenbank geschrieben wurden

[1] https://bugs.oxid-esales.com/view.php?id=6102