![]() |
Datenbank: Access oder auch was anderes • Zugriff über: ADO/ODBC
Record Locking mit Delphi
Hallo Zusammen,
ich weiss, dass dieses Thema nicht sonderlich populär ist (die Suche gibt 4 Treffer aus, welche mir nicht weiterhelfen), aber vielleicht kennt ja doch jemand wie man einen Datensatz in einer Datenbank via ODBC locken kann. ich stelle mir das wie folgt vor....
Code:
kennt jemand hierzu die konkreten befehle um so etwas zu realisieren?
lock record for update (primary index fields) in table xxx;
if locked then begin .... release locked record; end else fehlermeldung(record konnte nicht gelockt werden); Herzlichen Dank GreenHorn |
Re: Record Locking mit Delphi
In modernen DBMS ist Locking nur selten nötig, da dies durch eine Transaktionssteuerung teilweise umgangen werden kann oder sie besitzen besondere SQL-Erweiterungen wie "with lock" select .. for update" welchen dann ein Locking veranlassen.
Aus deiner Fragestellung geht jetzt nicht genau hervor, ob du mit Access arbeiten willst oder noch ein geeignetes DBMS suchst. Warum ODBC? |
Re: Record Locking mit Delphi
hallo MKinzler,
für keine Datenspeicherungen nehme ich gern Access, da die Daten in nur einer Datei abgespeichert werden. So lange das Progy auf nur einen Rechner läuft, fühle ich mich wohl. Wenn ich es jedoch im Netzwerk einsetzen möchte, kommt automatisch die Frage, wie kann man die Daten vor gegenseitigen überschreiben schützen. Dabei schwebt mir vor, dass zwischen den letzten lesen, wo der status in ordnung war und der update operation, der datensatz vor veränderung geschützt wird, nur wie kann man diesem entsprechend allokieren, damit er nicht verändert wird? Eine Abstraktionsschicht auf dem Server einzuziehen, bei dem die Datensätze "logisch" gesperrt werden können, ist eine Möglichkeit, hab nur keine Lust so ein Monster zu Programmieren, da dies doch eine Funktion der Datenbank sein muss (für was braucht man sonst eine Datenbank, um nicht die integrität der Daten zu gewährleisten). Hoffe dies dient zur Erläuterung. Wie umgeht Ihr so die Problematik des gegenseitigen überschreibens? Grüsse GreenHorn PS:
|
Re: Record Locking mit Delphi
Ich kenne mich mit Access (programmiertechnisch) nicht so aus, kenne nur dessen Zicken als Anwender und würde deshalb von dessen Anwendung abraten.
Wenn du ein richtiges DBMS einsetzt umgehst du deine Probleme. Vom MSSQL-Server gibt es verschiedene Versionen z.B. die MSDE/SQL2005 express oder compact, so das die Dateien transportabel sind. ODBC ist veraltet und einfach portierbar sind die Anwendungen dann trotzdem nicht. es gibt hier im Forum viele Beiträge, die sich mit DB-Alternativen beschäftigen, vielleicht findest du dann auch die Datenbank, die für deine Problem geeignet ist |
Re: Record Locking mit Delphi
Hallo,
Locking mittels ADO geschieht standardmäßig und vollautomatisch auf Page-Level (2048 Byte), sodass in der Regel mehr als ein Record gesperrt wird. Der Entwickler kann aber der automatischen Lock Escalation reinpfuschen, wenn er Sperren auf RecordSet- oder Database-Level anfordert. ODBC bietet keine Locking Funktionalität und sollte ADO über ODBC eingestzt werden, dann ignoriert ODBC Sperrversuche solange es geht und bringt ansonsten Fehlermeldungen. Bei den automatischen Sperrmechanismen lässt sich noch der LockMode einstellen: Optimistic oder Passimistic. SQL-Server arbeiten in der Regel optimistisch (Sperren so spät wie möglich), Access und Co. mit pessimistischen (so früh wie möglich) Sperren. Es ist Aufgabe des Entwicklers auf die Fehler zu reagieren, die durch konkurrierende Zugriffe im Mehrbenutzerbetrieb auftreten. Die Sperren selbst werden optimal von der Transaktionskontrolle der DB-Engine verwaltet. Grüße vom marabu |
Re: Record Locking mit Delphi
hallo Marabu,
wenn ich dich recht verstehe, brauche ich da nichts zu machen, da der Server das sperren automatisch übernimmt. demnach vom letzten lesenden auf dem schreibenden/lesenden zu griff. klingt ja nett... :thumb: nur so ganz glauben kann ich es nicht :gruebel: grüsse und noch einen schönen Sonntag. |
Re: Record Locking mit Delphi
Hallo,
hier noch ein wenig Hintergrundinfo, versteckt in den VB-Quellzeilen dieses Knowledgebase-Artikels: ![]() Dir auch noch einen schönen Sonntag. |
Re: Record Locking mit Delphi
GreenHorn3600: Access ist eine Desktop-Datenbanke (Einzelplatz), die mit viel Mühe mehr schlecht als recht auf 'Mehrbenutzer' getrimmt wurde.
Mehrbenutzerbetrieb und Access schließen sich gegenseitig aus, auch wenn immer noch sehr viele MB-Anwender mit Access entwickelt werden. Lass die Finger davon. Wir haben einen Lockmechanismus bei einer Kundenverwaltung implementiert: Benutzer A fordert Kundendatensatz XY an und will ihn verändern. Vorher schickt er eine Lock-Anforderung an die Mittelschicht. Sofern die Lockanforderung erfolgreich war, kann er den Datensatz verändern, die Änderungen speichern und den Lock wieder aufheben. Du musst dann Vorkehrungen treffen, das das 'Unlock' z.B. infolge eines Rechnerabsturzes nie aufgehoben wird, beispielsweise durch ein 'Zwangsunlock' nach 10 Minuten: Der Benutzer muss sich dann eben etwas beeilen. 100% vollautomatisch und ohne jegliche manuelle Eingriffe in seltenen Extremsituationen wird das nicht funktionieren, wiel nach Murphy immer irgendwo etwas schief geht. Nach meiner Erfahrung ist dieses Locking keine gute Idee, besser ist eine Konfliktbehandlung, also wenn zwei Anwender Änderungen am Datensatz simultan vornehmen wollen. |
Re: Record Locking mit Delphi
Zitat:
|
Re: Record Locking mit Delphi
Hallo Bernhard,
time flies. Dein von mir zitierter Satz bezog sich leider auf eine ältere Version von Access, denn soeben habe ich beim Recherchieren gelernt, dass Access 2000 seinen default lock mode auf Optimistic setzt. Darüber hinaus scheint Pessimistic bei diesem Produkt ein Synonym für Record-Level Locking zu sein. Die Page-Size wurde auch verdoppelt. ![]() Meine Aussagen bezogen sich in erster Linie auf MS Access, da der OP es bei seinem Beitrag als DBMS angegeben hat. Mit SQL Server 2005 habe ich noch keine Erfahrungen, aber wenn wir da von Neuerungen sprechen wollen, dann müsste das Thema RLV (Row Level Versioning - Hallo Interbase) heißen - oder? ![]() Ansonsten kennt schon der SQL Server 2000 eine Page-Size von 8KByte und insgesamt sechs Lock Typen, darunter zwei auf Record-Ebene: Einer sperrt Records auf einem Heap und der andere Records in einem Index. Ich vermute, dass diese Sperren nicht vom Entwickler kontrolliert werden können, bin mir aber keineswegs sicher. Ich verlinke mal Server Books Online 2005, da ich schlecht auf meine 2000-er Ausgabe verlinken kann: ![]() Freundliche Grüße |
Re: Record Locking mit Delphi
Ihr diskutiert zuviel was ihr wollt. Es wurde nach Locking gefragt, und nicht nach einer Abstimmung wer für und wer gegen Access ist.
Wie hier ja schon durchschimmert, musst du tatsächlich als Entwickler alles selber machen. Es gibt da mehrere Möglichkeiten: - Datensatz lesen. Er ist nicht gelockt. - Datensatz in der Anwendung ändern. - Datensatz soll gespeichert werden - dazu per Dataset (TQuery oder TTable) öffnen für Edit. Dadurch wird er gelockt. Jetzt nicht direkt schreiben sondern erstmal prüfen: Sind da die gleichen Daten drin wie du gelesen hast? Falls ja: Daten schreiben und speichern (Post). Falls nein: Meldung an Benutzer oder was-weiß-ich und schließen. Alternativ - da hast du weniger zu tun, nur legt ein anwender dann alle anderen still: - Connection öffnen - Transaktion starten. Bei MSSQL-Server würdest Du REPEATABLE READ nutzen. - Datensätze öffnen, wenigstens einen beschreiben (dadurch ist dann die gesamte tabelle für alle anderen benutzer gesperrt). - Datensätze in der anwendung verändern lassen und dann schreiben. - Transaktion beenden. Finde ich persönlich sehr schlechte lösung. Wäre aber wohl das, wonach du gefragt hast. Dritte Alternative, die auch schon oben angegeben wurde, aber nicht in einzelschritten: - Datensätze lesen und jeweils sperren indem du in eine andere Locking-Tabelle schreibst, wer welchen datensatz wann gesperrt hat. Beim lesen prüfst du natürlich, dass der zu lesende datensatz nicht schon gesperrt ist. - datensätze verändern und speichern - lcoking-eintrag entfernen. Problem wurde oben auch genannt: was ist wenn der rechner abstürzt. Dazu könnte man beispielsweise die oben erwähnte 10-min-regel machen. Eine ideale lösung gibt es dafür nicht. Die unterschiede sind: - ganz oben lockst du gar nichts und prüfst nur ob die daten in der zewichenzeit verändert wurden. Ggf wird der anwender eine "wurde verändert"-meldung bekommen. - in der mitte sperrst du so restriktiv, dass dem anwender der da sperrt nichts passieren kann, alle anderen in dem moment aber nicht arbeiten können. das ist natürlich in einer mehrbenutzerumgebung ein ko-kriterium. - und unten sperrst du indirekt durch die locking-tabelle, die du selbst verwaltest. der nachteil ist, dass bei rechner-absturz evtl. datensätze erstmal nicht mehr erreichbar sind (für die anderen). aber diesen nachteil kann man wie gesagt ganz gut lösen. also nichts mit automatisch. PS: um auch nochmal was zu access zu sagen: Leute die schreiben: "Access ist scheiße. Hab nie damit gearbeitet, ist aber so!"... was soll man denn von denen halten? Wir haben alle unsere vorurteile gegen microsoft, aber ich habe viel mit access gearbeitet und muss sagen: Wenn man diese DB richtig einsetzt, dann ist sie wirklich sehr sehr gut! Sehr stabil, mir ist noch nie eine DB kaputt gegangen, sehr performant und so weiter. Es ist nunmal eine Desktop-Datenbank, die hat ihre Grenzen. Aber die meisten anwendungen können mit diesen grenzen gut leben (wer verwaltet schon 60 Mio Kunden). Und auch in Mehrbenutzerumgebungen hatte ich mit Access nie Probleme. Das wirkliche Problem bei Access ist, dass es relativ leicht ist, sich dort was zurechtzuklicken. Daraus entstehen dann datenbanken, die nicht wartbar sind, weil die ersteller keine ahnung hatten. Da ist das problem aber nicht access, sondern die ersteller der dbs sind das problem. Also schimpft nicht immer gegen access solange ihr die db nicht wirklich kennt. Euer geschimpfe zeigt nur eure ignoranz und eigentlich zeigt ihr damit nur, dass ihr euer fähnchen in den wind haltet. |
Re: Record Locking mit Delphi
[quote="bttb930"]
- Datensatz lesen. Er ist nicht gelockt. - Datensatz in der Anwendung ändern. - Datensatz soll gespeichert werden - dazu per Dataset (TQuery oder TTable) öffnen für Edit. Dadurch wird er gelockt. Jetzt nicht direkt schreiben sondern erstmal prüfen: Sind da die gleichen Daten drin wie du gelesen hast? Falls ja: Daten schreiben und speichern (Post). Falls nein: Meldung an Benutzer oder was-weiß-ich und schließen./quote] Hallo, geht besonders einfach wenn ein extra Feld (not nullable) bspw. ("rowversion") in jeder Tabelle mit dabei ist und bei jedem update der Zeile hochgezählt wird. Damit kann schnell und einfach ein konkurierendes Update erfaßt und darauf wie auch immer reagiert werden. Initialisieren beim Insert mit 0 wäre dabei hilfreich :wink: |
Re: Record Locking mit Delphi
Zitat:
|
Re: Record Locking mit Delphi
Außerdem heißt der Thread ja "Access oder auch was anderes"
|
Re: Record Locking mit Delphi
Hallo,
aus "habe ich gehört und gesehen" 20 gleichzeitige Nutzer bremsen Access extrem aus. Absturz, Exclusiv reingehen, reparieren, weiter Ein Umstieg auf SQL-Server (per Access Project) gehob das Problem. Zu den Locks und den 10 Minuten. Führe eine Locking-Tabelle mit, in der UserId, Tabelle (Id), zu lockender PrimKey und Datum/Uhrzeit) mitgelockt werden. Und nu kommst !! ;) Per Timer oder Thread werden die aktuellen Locks aufgefrischt, also Datum/Uhrzeit aktualisiert. Schmiert das Programm ab, "verfällt" die Sperre irgendwann (z.B. nach 5 Minuten) Beim Start der App oder beim Setzen irgendeines Locks werden alle Locks < X Min gelöscht (am besten per stored procedure). Die Tabelle hat den Vorteil, dass man auch eine Meldung ala "Datensatz wird gerade bearbeitet von XXX seit YYY" Zum Locken allgemein. Ein Locken bei Mehrbenutzerbetrieb ist notwendig. Wenn ich einen Kunden bearbeiten will und verhindern will, dass zum gleichen Zeitpunkt das jemand anders soll, was bliebt mit anderes übrig ? Das Locken hat hier natürlich nichts mit den DB-Locksbei konkurrierenden Zugriffen zu tun, sondern ein lock innerhalb der Anwendung. Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:57 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 by Thomas Breitkreuz