Ich habe ein Problem bei der Entwicklung einer Validierung und eigener Datenfortschreibung für Allokationen (CO-Belege) . Bei der Ausführung von Zyklen werden öfters mehrere Belege gebucht und dabei wird der Verbucher einzeln pro Beleg aufgerufen.
Ich setzte Sperren auf unsere Objekte bereits bei der Validierung der Belegzeilen, damit man den Prozess im Fehlerfall abbrechen kann. Wenn ich den Parameter _SCOPE = 2 setze, habe ich das Problem, dass die Verbuchung asynchron verläuft und die Sperren zu spät freigegeben werden, teilweise wenn ich die Validierung für den nächsten Beleg schon durchgeführt habe. Dann laufe ich auf den Fehler, falls ein Objekt gesperrt werden soll, kann aber nicht, weil noch von der Verbuchung gesperrt ist.
Deshalb dachte ich mir, das sich die Sperren im Dialogprozess setzen muss.
Jetzt habe ich die Option _SCOPE = 3 ausprobiert, habe aber nicht verstanden, was die Verbuchung dabei macht. Kennt sich jemand aus?
Wird für jede CALL FUNCTION IN UPDATE TASK ein neuer zweiter Eigentümer gesetzt?
Gilt die Sperre der ersten Verbuchung auch für die zweite Verbuchung, falls diese nicht erneut gesetzt wird? oder muss die Sperre vor jeder Verbuchung erneut gesetzt werden?
Ich arbeite dabei mit einer Funktionsgruppe und speichere die gesperrten Objekte in einer globalen internen Tabelle der FuGr. Ich habe gemerkt, dass beim Stornieren und anschliessenden Ausführen des Zyklus die Funktionsgruppe ein mal neu gelageden wird. Dabei ist die globale Tabelle leer und ich habe keine Infos mehr darüber, welche Objekte ich gesperrt habe.
Wie kann ich feststellen, dass die Funktionsgruppe neu geladen wurde?
Oder kann ich alle Sperren eines Workprozesses irgendwie ermitteln? Die Lebensdauer von Sperren kann ich nicht an die Lebensdauer der Funktionsgruppe binden oder?
Probier mal den Befehl SET UPDATE TASK LOCAL. Damit erzwingst du eine lokale Verbuchung.
Funktioniert aber nicht, wenn du die Verbuchung per Call Transaction aufrufst (Batchinput).
den Befehl COMMIT WORK kann ich nicht ändern, das ich nur einen User-Exit implementiere und nicht in das Rahmenprogramm eingreifen kann. Die Verbuchung kann leider nur asynchron stattfinden.
wir wollen unser Produkt so weit wie möglich in den SAP-Standard integrieren und die Kunden wollen möglichst wenige extra-Transaktionen parallel zu SAP-Transaktionen bedienen. Deshalb arbeiten wir viel mit Events und User-Exits, so weit es geht.
Im Großen und Ganzen würde die Fortschreibung gehen, wenn nicht das SAP-Sperrkonzept und das willkürliche Starten von Workprozessen durch das Rahmenprogramm, den man nicht mitkriegt... Vielleicht sollte ich deinem Vorschlag folgen.
halte doch das Ganze im Debugging nach dem Setzen der ersten Sperrargumente einmal an. In einem anderen Modus testst Du dann den Funktionsbaustein ENQUE_READ2 und gibst die Felder GCLIENT und GUNAME mit. Heraus kommt eine interne Tabelle mit den Sperren (der FUBA wird auch in der SM12 ermittelt). Sicher lassen sich die gesetzten Sperreinträge in der Tabelle identifizieren.
Nach dem Absetzen der Verbuchung kannst Du den FUBA solange in einer DO-Schleife starten, bis die Sperren verschwunden sind. Peinlich wird es nur, wenn die Sperren aus unerfindlichen Gründen nicht frei gegeben werden .. also nach einer Million Durchläufen alles mit einer Fehlermeldung abbrechen. Alles nicht gerade elegant, funktioniert aber, wenn nicht gerade iim unglücklichsten Moment ein zweiter das gerade verbuchte Objekt ändern will.
Ich hatte mal mit einem ähnlichen Problem zu kämpfen. Ein User legt mit der CO01 (dabei eine Modifikation) einen Fertigungsauftrag an. Danach wurde in der Modifikation die CO02 gestartet, um die Abrechnungsvorschrift zu ändern
... aber: die CO01-Verbuchung war durch, die Sperre aber noch nicht. Der User war nun schneller und machte mit der CO02 weiter um noch was zu ändern ... hat mich eine ganze Weile beschäftigt.
ich werde es mal ausprobieren. Bei mir im System gibt es nur den FuBa ENQUE_READ, aber ich denke, dass er der richtige ist.
Als Alternative teste ich jetzt andere Variante: ich setze die Sperren nur für den Verbucher (mit _SCOPE = 2) und mus die Sperren nicht merken, weil diese automatisch freigegeben werden. Beim nächsten Beleg setze ich die Sperren mit dem Parameter _WAIT = 'X'. Vielleicht baue noch auch eine Warteschleife drum... Ob es gut funktioniert, kann ich nur in einem Belastungstest mit großen Belegen feststellen.
Danke für den Tip, ich denke, das hilft mir weiter.