Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Rechnungsnummern fortlaufend - Multiuser

Begonnen von Milvus, Januar 28, 2019, 19:50:47

⏪ vorheriges - nächstes ⏩

Josef P.

Hallo!

ZitatIch dachte da eher an Buchhaltungsbelege, wo zu jedem Augenblick sichergestellt werden muß, daß alle Buchungszeilen aller Belege miteinander auf 0 aufgehen.
So etwas muss dann natürlich unbedingt in einer Transaktion laufen.
Ich würde dann aber auch überlegen, ob ein File-Datenbanksystem eine gute Basis für ein Buchungssystem ist.


ZitatWenn man DMax verwendet, wird die Funktion dann auch noch automatisch im Kontext derselben Transaktion ausgeführt, oder müsste man dafür dann den kompletten Aufruf aus VBA nochmal explizit in einer Transaktion kapseln?
Wie könnte man das herausfinden?

Ohne zu wissen, ob die Abfrage-Transaktionseinstellung ausreicht:
Ich würde zur Sicherheit eine Transaktion in VBA vor dem SQL-Aufruf starten, damit sie im DBEngine-Umfeld läuft. Das müsste dann meiner Meinung nach auch DMax erwischen, da ich davon ausgehe, dass DMax die identische DBEngine-Instanz verwendet.


Bezüglich Rechnungsnummer schreiben, ist das meiner Meinung nach aber nicht so kritisch. Das sollte ohne Transaktion richtige Daten liefern. Es muss aber unbedingt eine Fehlerbehandlung einen möglichen Konflikt abfangen.

[OT]
Bei diesen Überlegungen merkt man erst, wie komfortabel es ist, wenn man einen SQL-Server o. ä. verwenden kann. ;)

mfg
Josef

Wurliwurm

Zitat von: Josef P. am Januar 31, 2019, 09:41:11
Ich würde dann aber auch überlegen, ob ein File-Datenbanksystem eine gute Basis für ein Buchungssystem ist.
Die Antwort ist sowieso klar: Nein, ein Access-Backend kommt nicht in Frage. Man kann in seinen SQL-Statements und in seinen VBA-Schleifen die tollsten Verrenkungen machen, wenn die Datenbankengine darunter nicht für Serialisierung geeignet ist und nicht für den Multiuserbetrieb skaliert, kann man es vergessen.

Milvus

Zitat von: Josef P. am Januar 30, 2019, 14:52:56
Ein Max(Rechnungsnummer) from Rechnungstabelle reicht aus um den höchsten Wert zu ermitteln.

Reicht eben nicht.

Problem: Bei gleichzeitigem Zugfriff mehrerer User wird die gleiche Nummer für mehrere Rechnungen verwendet (da der Prozess ja mehr als inifinitisimal wenig Zeit braucht).

Das wollte ich mit einem AddNew in eine Tabelle mit Autowert eben ausgleichen, somit steht dieser Wert "nur" dem Auserwählten zur Verfügung.

Mit obigem Ansatz, erst mal eine Draft zu erzeugen und dann erst im nachgelagerten Schritt die Nummer zu erzeugen wird die Gefahr eines Abbruchs (=Lücke) deutlich reduziert. Nur 2 Schritte: Erzeuge Nummer , schreibe in Re-Tabelle.


Milvus

Zitat von: Wurliwurm am Januar 30, 2019, 16:08:37
Eine Lösung wäre ein Sperrtabelle, in der vor dem Beginn der Transaktion die neue (Max+1) Nummer eingetragen (reserviert) wird. In der Rechnungsbuchungstransaktion wird die neue Nummer am Schluß dann wieder aus der Sperrtabelle rausgekickt. (Sauber ist es, wenn auch bei Buchungsabbrüchen aus irgendwelchen Gründen die reservierte Nummer nicht in der Sperrtabelle stehenbeibt). Genaugenommen kann es aber auch beim Insert in die Sperrtabelle die gleichen Konflikte geben, so daß sich das Problem nur verlagert.

Negativ! Diese Lösung ist bereits etabliert und versagt (warum auch immer), übrigens nicht nur bei der Rechnungsthematik.

Daher der Ansatz, das Sperren/Reservieren der Datenbank zu überlassen.

Wurliwurm

Zitat von: Milvus am Februar 21, 2019, 09:47:31
Zitat von: Wurliwurm am Januar 30, 2019, 16:08:37
Eine Lösung wäre ein Sperrtabelle, in der vor dem Beginn der Transaktion die neue (Max+1) Nummer eingetragen (reserviert) wird. In der Rechnungsbuchungstransaktion wird die neue Nummer am Schluß dann wieder aus der Sperrtabelle rausgekickt. (Sauber ist es, wenn auch bei Buchungsabbrüchen aus irgendwelchen Gründen die reservierte Nummer nicht in der Sperrtabelle stehenbeibt). Genaugenommen kann es aber auch beim Insert in die Sperrtabelle die gleichen Konflikte geben, so daß sich das Problem nur verlagert.

Negativ! Diese Lösung ist bereits etabliert und versagt (warum auch immer), übrigens nicht nur bei der Rechnungsthematik.

Daher der Ansatz, das Sperren/Reservieren der Datenbank zu überlassen.


Wenn die Lösung nicht funktioniert, ist sie möglicherweise nicht sauber geschrieben. Bist Du sicher, daß Du da bei dem Aufspannen der Transaktionen alles sauber machst? Daß sie bei großer Last mit etlichen konkurrierenden Zugriffen bei einem Access-Backend nicht immer 100%ig funktionieren kann, habe ich ja weiter oben schon angesprochen.

Nummernvergabe der Datenbank zu überlassen, ist immer der richtige Weg. Es handelt sich ja um ein Standardproblem und deshalb gibt es in Datenbanken ja eine Möglichkeiten, Sequenzen (aufsteigende Nummern) anzulegen. Nicht zu verwechseln mit dem Autoincrement von MS-Access.

Josef P.

#20
Hallo!
Zitat
Problem: Bei gleichzeitigem Zugfriff mehrerer User wird die gleiche Nummer für mehrere Rechnungen verwendet (da der Prozess ja mehr als inifinitisimal wenig Zeit braucht).
Eine Updateanweisung für einen einzigen Datensatz inkl. einer Max-Auswertung auf einen Index sollte eigentlich in Bruchteilen einer Sekunde erledigt sein.
Die Rechnungsnummer darf natürlich nicht als Standardwert über die Rechnungsmaske vergeben werden, sondern muss beim Speichern des Datensatzes bzw. sobald eine Nummer fixiert werden darf geschrieben werden.

Noch mal:
1. Anwender öffnet Rechnungsmaske und beginnt den Inhalt zu bearbeiten ... es gibt noch keinen Wert (oder nur einen Dummywert wie TMP-[Autowert] als Rechnungsnummer
2. Anwender speichert den Datensatz ... Rechnung ist noch nicht frei = es gibt immer noch keine Rechnungsnummer
3. Anwender gibt Rechnung frei => Jetzt wird per Update-Anweisung die nächste freie Rechnungsnummer eingetragen.
Sollte es zu einem Konflikt mit dem eindeutigen Schlüssel auf die RE-Nr kommen, weil zu gleichen Zeit ein anderer User auch die Rechnung frei gab, wird das per Fehlerbehandlung abgefangen und der Update-Prozess erneut ausgeführt.
Wichtig ist der eindeutige Index auf die Rechnungsnummer. Nur damit ist sichergestellt, dass es zu keiner Doppelvergabe kommen kann.

mfg
Josef