AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Einzelne Zeile in Tabelle sperren (lock row)
Thema durchsuchen
Ansicht
Themen-Optionen

Einzelne Zeile in Tabelle sperren (lock row)

Ein Thema von Incocnito · begonnen am 17. Apr 2020 · letzter Beitrag vom 20. Apr 2020
Antwort Antwort
Incocnito

Registriert seit: 28. Nov 2016
230 Beiträge
 
#1

AW: Einzelne Zeile in Tabelle sperren (lock row)

  Alt 20. Apr 2020, 07:47
...
PgScript ist böse, denn es teilt an den ; den Text auf und sendet alles als einzelne Abfragen zur DB.
(macht Spaß, wenn das Aufteilen nicht an den richtigen Stellen schneidet)
...
Danke schonmal für den Hinweis! Das hätte ich tatsächlich als nächstes versucht,
aber dann brauche ich das damit gar nicht erst versuchen.

...
Beim PgQuery kann man einstellen was es macht, womit sich da auch de-/aktivieren lässt, dass mehrere Befehle gehen (kann auch sein, dass eine Option an der Connection war)
Ich denke mal sowas hast bei dir umgestellt oder vergessen zu machen.
...
Zumindest finde ich diese Einstellung nicht.

...
Statt BEGIN und COMMIT kannst du aber bestimmt auch die Transaktion über die Connection-Klasse starten, bzw. mit einem Transactionsmanager an der Connection.
Ich will keine in sich geschlossene Transaktion starten.
Daher wunderte es mich, dass "BEGIN ... COMMIT;"
sich (im pgAdmin) auftrennen lässt auf zwei nacheinander ausgeführte Querys.
Aber es macht genau das, was ich brauche.

Hallo,
Lock auf DB-Ebene ist auf jeden Fall keine gute Idee.
...
Kannst du das begründen?

Das dort gezeigte Beispiel verwendet mehrere Befehle (was ja bei mir nicht geht) und außerdem
wird das als Beispiel für einen Vorgang genommen, welcher "in einem Rutsch" durchgeführt wird.

Ich würde mal in Frage stellen, ob so eine Workflow Aktion (Reservierung) über solche Mechnismen sinnvoll ist.
M.E. ist das ein Bestellstatus ("ImWarenKorb"), der den Artikel aus dem Lager entfernt.
...
Dann habe ich das vielleicht nicht gut genug erklärt.
Stellen wir uns vor, wir hätten einen Kassiervorgang bei dem nun ein Arikel hinzugefügt werden soll.
Hier bietet sich wunderbar eine Transaktion an:
- Position hinzufügen
- Ware aus dem Bestand/Lager entfernen
- meinetwegen noch in den Kopfdaten die Summenwerte anpassen (ist zwar doppelte Datenführung wird aber gerne gemacht, auch als Kontrolle für konsistente Daten)
Das alles passiert in einem Rutsch. Nur in mehreren Tabellen.
Also sehe ich hier eine ideale Verwendung für Transactions.
Zumindest habe ich so Transaktionen bisher mit solchen Aktionen in Verbindung gebracht.
Da wäre ich tatsächlich bei dir:
- Eine seperate (evtl. neue?) Connection
- Transaction Start
- Alle Querys nacheinander so wie man das gerade braucht und/oder möchte
- Transaction Ende
Wunderbar. Dann wäre es auch völlig egal, dass ich pro Query.ExecSQL(); nur einen Befehl abschicken kann.

Jetzt will ich aber sowas gar nicht.
Ich will eher sowas wie das Bearbeiten eines Kunden im Kundenstamm.
Ich habe unzälige Mitarbeiter in der Firma.
Einer öffnet den Kundenstamm und will diesen bearbeiten.
Beim Bearbeiten muss dieser eine Datensatz im Kundenstamm gegen das Bearbeiten
durch andere Mitarbeiter gesperrt sein. Sicher kann man noch einbauen,
dass wenn der Mitarbeiter Kaffee holen geht und die Maus 10 Minuten nicht bewegt wird,
dass das Bearbeiten dann abgebrochen wird oder was auch immer man lustiges machen möchte.
Ich brauche aber dafür halt einen Mechanismus der sicherstellt,
dass der Datensatz für andere zum Bearbeiten gesperrt ist.

Ich hoffe du erkennst an dem Beispiel besser was ich will.
Du hängst mit dem Warenkorb-Beispiel tatsächlich eher bei einer Transaction (1 Event)
und weniger bei einem Lock (2 zeitlich unabhängige Events).
(Auch wenn innerhalb der Transaction ja schon der SQL-Befehl für "Lock" benutzt wird.)

Hier vielleicht noch angemerkt, dass ich keinen Anspruch darauf erhebe, dass ich
die Wörter "Lock" und "Transaction" tatsächlich richtig versetehe, aber so sollen
sie zumindest in meinen Posts gedacht sein und so passt es meines Erachtens nach auch
am Ehesten zu den Beschreibungen, welche ich bisher so gelesen habe.

...
Ansonsten:
Die Query Komponenten, die ich kenne machen automatisches Transaktionshandling und sind nicht fähig, mehrere Befehle zu verarbeiten.
Man kann in PG wie in Deinem Beispiel anonyme Blöcke nutzen, aber (natürlich) auch nicht in 2 separaten Queries.
...
In pgAdmin kann ich (wie oben schon erwähnt) tatsächlich das "BEGIN" und das "COMMIT" in zwei zeitlich unabhänige Query schreiben. Das funktioniert und macht genau das, was es soll.

---

Unterm Strich: Wie löst ihr das Sperren von Stammdaten zum Bearbeiten?
Oder habt ihr andere Komponenten, bei denen das so funktioniert wie es auch in pgAdmin selbst funktioniert?
Stört ihr euch vielleicht gar nicht daran, wenn Anwender einen Datensatz
von zwei Stationen bearbeiten können?
Bei ADS (Advantage Datebase Server) sperrt die Table-Komponente den Datensatz,
wenn man "TheTable.Edit();" verwendet (bis zum TheTable.Post().
Ich meine bei MySQL/MyDac genau so.
Wenn ich also raten soll, würde die UnitTable das auch machen.
Also werde ich wohl mal darüber versuchen was zu bauen, erscheint mir aber irgendwie falsch/affig.

Liebe Grüße und Danke schonmal für die Zeit und Hilfe bis hierher
Incocnito
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.277 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Einzelne Zeile in Tabelle sperren (lock row)

  Alt 20. Apr 2020, 07:55
Hallo,
du könntest das auf Anwendungsebene implementieren,
z.B. mit einer Sperrtabelle.

Bei Interbase(Firebird hatte ich mal das folgende gepostet

https://www.delphipraxis.net/746237-post.html#854092
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
725 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Einzelne Zeile in Tabelle sperren (lock row)

  Alt 20. Apr 2020, 08:40
Hallo,
du könntest das auf Anwendungsebene implementieren,
z.B. mit einer Sperrtabelle.
Jup. Sowas machen wir auch.
Hat nebenbei noch den Vorteil das man darüber auch Programm Module die nur einmal laufen dürfen verwalten kann.
Dazu gibt es eine Registrierung aller Nutzer zu deren existierenden Connections so das SQL Scripte automatisch wissen unter welchem Nutzer sie laufen und auswerten können welcher Nutzer gerade einen Datensatz besitzt.
Das funktioniert unter ADS Server mit transaktionsfreien Tabellen und unter MS SQL Server via UniDac mit Transaktions ignorierenden Befehlen.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.438 Beiträge
 
Delphi 12 Athens
 
#4

AW: Einzelne Zeile in Tabelle sperren (lock row)

  Alt 20. Apr 2020, 08:10
Moin...
Zitat:
Beim Bearbeiten muss dieser eine Datensatz im Kundenstamm gegen das Bearbeiten
durch andere Mitarbeiter gesperrt sein. Sicher kann man noch einbauen,
dass wenn der Mitarbeiter Kaffee holen geht und die Maus 10 Minuten nicht bewegt wird,
dass das Bearbeiten dann abgebrochen wird oder was auch immer man lustiges machen möchte.
Ich brauche aber dafür halt einen Mechanismus der sicherstellt,
dass der Datensatz für andere zum Bearbeiten gesperrt ist.
...eine eigene Lock Tabelle in der DB. Vor dem Bearbeiten wird geguckt ob der Datensatz in Benutzung ist. Nach dem Bearbeiten wieder freigeben.
Die Umsetzung ist natürlich etwas komplizierter:
* in der Lock Tabelle werden gespeichert Computername, User, Wann, Datensatz ID ...etc.
* jeder kann seinen gesperrten Datensatz bearbeiten. (Computerabsturz)
* für den Fall, daß die Putze über das Netzwerkkabel gestolpert ist, kann der Adminstrator des Programmes alle oder bestimmte Sperren zurücksetzen.

Vorteil:
1. kein Locking in der DB!
2. über die Datensatz ID (Kunde etc.) kann man auch die Detaildaten des Kunden sperren. (Zahlungen z.B)
3. automatisches Rücksetzen der Sperre mit Info an den User
...es sind der Kreativität keine Grenzen gesetzt.

Geändert von haentschman (20. Apr 2020 um 08:16 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#5

AW: Einzelne Zeile in Tabelle sperren (lock row)

  Alt 20. Apr 2020, 09:33
Unterm Strich: Wie löst ihr das Sperren von Stammdaten zum Bearbeiten?
Oder habt ihr andere Komponenten, bei denen das so funktioniert wie es auch in pgAdmin selbst funktioniert?
Stört ihr euch vielleicht gar nicht daran, wenn Anwender einen Datensatz
von zwei Stationen bearbeiten können?
Als ich sowas mal brauchte, habe ich das über zwei extra (nullable) Spalten gelöst: LockedBy und LockTime. Aber man kann das natürlich auch in eine extra Tabelle auslagern - es ist letztlich eine 0-1:1 Beziehung (0-1 locks pro Datensatz) mit Feldern je nach Bedarf. Bearbeitung nur erlaubt, wenn das Lock dir gehört.

Jede Nacht werden alle locks gelöscht - bei mehr Traffic würde ich aber einen cutoff einbauen und sagen, locks die älter sind als z.B. 1h sind irrelevant.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz