![]() |
Mehrbenutzerzugriff mit ADO und MSSQL
Hallo,
ich soll in unserer Firma ein kleines Verwaltungsprog schreiben das Multiuser fähig ist. Eigentlich dachte ich, das das nicht soo schwer sein kann, aber weit gefehlt. Ich komme seit einer Woche irgendwie nicht weiter. Entweder ist es so einfach, das niemand drüber spricht, oder ich bin zu doof :wall: Ich habe halb Google auswendig gelernt, aber irgendwie war nicht das richtige dabei. Ich hoffe bei Euch gibt es Leute die sowas schonmal gemacht haben. :? Also, ich schreibe erstmal was ich bereits verwende und was ich schon alles Versucht habe. Ich möchte per Delphi ADO Komponenten auf einen MSSQL2000 Server zugreifen. Dazu verwende ich TADOConnection und TADOQuerry. Ich habe schon oft gelesen man solle die BetterADO verwenden, allerdings ist der Download nicht zu erreichen. Es sollte ja auch mit den eigenen Komponenten klappen. Ich habe folgendes bereits gemacht: Der user sieht ein DBGrid dessen Inhalt über ein Querry gefüllt wird. Nun soll man einen Datensatz doppelklicken und ein Detailfenster erscheint wo nun die Änderungen gemacht werden können. Mit OK wird das Fenster geschlossen und die Daten geschrieben. Die Prozedur mit der ich die Daten schreiben sieht folgendermaßen aus:
Delphi-Quellcode:
Das ganze klappt ja eigentlich schon ganz gut nur bekomme ich das Problem nicht in den Griff, das
procedure Datenupdaten;
begin Form1.ADOConnection1.BeginTrans; try With Form1.Artikel do Begin SQL.Text:='UPDATE Artikel SET ArtNr=:_ArtNr, ArtName=:_ArtName WHERE ID=:_ID'; Prepared := True; With Parameters Do Begin ParamByName('_ArtNr).Value := Form_Arikel.Edit1.Text ParamByName('_ArtName).Value := Form_Artikel.Edit2.Text; End; Form1.QKunde.ExecSQL; end; Form1.ADOConnection1.CommitTrans; except on E: Exception do Form1.ADOConnection1.RollbackTrans; end; Form_Arikel.Close; end; zwei User die Detailmaske eines Artikels aufmachen, -User1 Kaffee trinken geht -User2 etwas ändert und speichert -User1 zurückkommt und seine eigenen Änderungen speichert bzw. einfach nur OK drückt und die alten daten zurückschreibt. Damit sind dann die Änderungen von 2 einfach weg. :( Es ist übrigens ausdrücklich gewünscht, das alle User den selben Datensatz lesen können, aber nur der "erste" ihn auch ändern und speichern kann. Die anderen sollen halt dann nur "schnell was nachschauen" dürfen. Ich hoffe Ihr wisst was ich meine. Überall im Netz finde ich Bruchstückhafte Anweisungen wie das zu lösen sei. Konkrete Codeschnipsel sind allerdings immer Fehlanzeige. Auch die OH von delphi und MSSQL geben nur wenig Aufschluß. Die Möglichkeit der Sperrtabelle finde ich recht unelegant, da muss der Zeitstempel ein Verfallsdatum haben damit nach einem Absturz der Datensatz nicht ewig gesperrt bleibt und so weiter... Ich habe auch schon etwas von
SQL-Code:
gelesen, nur scheint das nur mit MySQL zu laufen.
SELECT ... FOR UPDATE
Bei MSSQL gibt es einen Fehler der besagt das es nur in Verbindung mit CURSOR möglich sei. - Hmmpf. An anderer Stelle wurde gesagt das das innerhalb der UPDATE Klausel geht, etwa so:
SQL-Code:
So würde nur ein Update geschehen wenn sich die Daten in der Zwischenzeit nicht geändert hätten, und eine Exeption ausgelöst sofern die Daten nicht eingefügt wurden. Ich weiss nur nicht wie das gehen soll :cry:
UPDATE Tabelle
SET SpalteA = 1, SpalteB = 2 WHERE SpalteA = 'Alte Daten von A' AND SpalteB = 'Alte Daten von B' Ich bin total verzweifelt, weil ich nirgendwo mal ein echtes stückchen Code, oder Anleitung finden konnte, die ich hätte adaptieren können. Bin ich denn der einzige Mensch der dieses Problem hat? Es gibt doch tausende von Multiuser Anwendungen die genau so funktionieren. Ich würde mich riesig freuen, wenn jemand mir da weiterhelfen könnte. Oder mir auch sagen, das ich so wie ich das vorhabe, auf dem Holzweg bin. Wenn keiner ein Stück Code hat, gibt es vieleicht gute Bücher die das Problem konkret beschreiben? Ich habe hier schon einen Stapel, aber die sprechen mit Vorliebe über Interbase... Bitte, bitte, bitte, ich brauche eine :idea: in diesem Sinne grüße Peter :dp: :dp: *schleim* :zwinker: |
Re: Mehrbenutzerzugriff mit ADO und MSSQL
Hallo Namenskollege,
vieleicht bringt dir ja der Beitrag ![]() |
Re: Mehrbenutzerzugriff mit ADO und MSSQL
Man könnte ja auch ein weiteres Attribut in die Entität einfügen, in dem du einen Wert setzt in dem du den Datensatz logisch sperrst.
Wichtig ist das du dabei Transaktionen verwendest, damit bei einem Rechner/Programm-Abstürz nicht der DS für immer gesperrt bleibt. [EDIT/WICHTIG] Herzlich Willkommen in der DP |
Re: Mehrbenutzerzugriff mit ADO und MSSQL
@ Bernhard
Hallo, das ist ja witzig :-D Soo häufig ist der Nachname jetzt ja nun auch nicht. Aber ich komme aus Kiel, bei Dir hört sich das eher nach Süden an... Ja, Hmmm, ich hab den Beitrag schon gelesen, nur irgendwie hatte der mich auch nicht so richtig weitergebracht. Denn die endgültige Lösung gibt´s dort auch nicht. @neo :wiejetzt: ich oute mich auch gerne als >Dummer Sack<, aber ich hab nicht wirklich viel verstanden von dem was Du geschrieben hast. Ausser natürlich Zitat:
Wie mach ich denn nu weiter? Soll ich meinen Code verbrennen, oder kann ich damit noch was reißen? danke und Grüße Peter |
Re: Mehrbenutzerzugriff mit ADO und MSSQL
|
Re: Mehrbenutzerzugriff mit ADO und MSSQL
Zitat:
Zitat:
|
Re: Mehrbenutzerzugriff mit ADO und MSSQL
Erstmal enttschuldigung, war kurz vorher bei der DB-Vorlesung an der Hochschule.
Zitat:
Entität = Tabelle Mit Logisch Sperren meine ich du setzt einfach einen Wert für, ist gerade in Bearbeitung! Ich hoffe das ist jetzt klarer. |
Re: Mehrbenutzerzugriff mit ADO und MSSQL
Da muss man nicht erst in einer Tabelle was setzten.
Du musst die jenige Transaktionseistellung wählen die jedem Leserechte gibt, aber nur dem jenigen, der als erster zugreift auch Schreibrechte genehmigt. Leider hab ich keine Ahnung wie das bei ADO hies. LockOptimistic oder so. Beim Interbase heisst die Einstellung Snapshot Table Stability (Nur-Lesen Tabellenstabilität) |
Re: Mehrbenutzerzugriff mit ADO und MSSQL
Zitat:
Die Problematik ist ja eigentlich folgende: Ernie & Bert arbeiten beide am gleichen Projekt. Dabei halten sie sich aber meistens an verschiedenen "Ecken" der dazugehörigen Tabellen auf. Ab & zu gibt's mächtig Zank weil Bert schon wieder Ernies Arbeit überschrieben hat ohne es zu bemerken. Jetzt kommt Samson und baut das ein, was Generalissimo vorgeschlagen hat. Die Folge ist, dass ENTWEDER Ernie ODER Bert arbeiten können. :arrow: Daraufhin wurden dann beide ziemlich stinkig. :mrgreen: Kurz und knapp: Dieses extreme Sperren der Tabellen ist in der Praxis alles andere als benutzerfreundlich. Zitat:
Mitagspause ist zu Ende. Ernie öffnet die Tabelle um 14:00. Bert hat sich schon 13:45 vollgefressen unter seinen Schreibtisch gequetscht. Um 14:01 speichert Bert. Was nun? Ich mache es mir dabei ziemlich einfach. In Oracle gibt es eine Pseudospalte namens RowID, die ist IMMER eindeutig (sie beschreibt schließlich die physische Position des DS auf der Fäschtpladde). Desweiteren können sich Sessions auf 2 Arten miteinander "unterhalten":
Beim Öffnen der Tabelle hat sich Ernies Session für ein Alert flag namens "Sesam Straße" registriert. An der Tabelle sitzt ein before-Update Trigger, der für jeden geänderten Eintrag ein Flag mit der RowID verchickt. Als Berts Session jetzt ein Commit absetzt bekommt Ernie mit, dass sich 3 Einträge geändert haben. Diese 3 Einträge kann man jetzt abfragen und mit der derzeitigen Ansicht synchronisieren. (unter .Net ist das ein 3-Zeiler, unter Delphi32 wird's ein Krampf ;) ). Bei Überschneidungen kann Ernie jetzt PRO Eintrag gefragt werden, ob er seine lokalen Änderungen verwerfen, oder lieber Berts Eintrag überschreiben will. So, mein Oraclekrempel ist gerade fertig geworden (in der Langeweile wurde aus dem Post glatt 'ne Episode Sesam straße :lol: ) OT: Das ist ein schreibfähiger Cursor in Oracle :mrgreen:
SQL-Code:
Interessant wird es mit der Erweiterung...
SELECT ... FOR UPDATE
SQL-Code:
Dann springt er dir in dem befürchteten Fall sofort ins Gesicht. (Aber ohne die fancy Möglichkeiten die eine Kommunikation zwischen den Sessions ermöglicht. ;) )
SELECT ... FOR UPDATE NOWAIT
|
Re: Mehrbenutzerzugriff mit ADO und MSSQL
Moin, danke erstmal für die vielen Vorschläge,
Zitat:
aber wenn ich fragen würde wie ich in ein Edit etwas reinschreibe würde als Antwort kommen:
Delphi-Quellcode:
Klar das ist ja auch einfach :roteyes:
Edit1.text:='Herr Bert';
Es will einfach nicht in meinen Kopf das, Delphi, ADO und MMSQL für dieses "wirklich seltene und fast nie vorkommende" Problem keine Lösung in der Tasche hat. :twisted: @Robert Danke für die wirklich schöne Sesamstraßen Episode :thuimb: Genau von dem beschriebenen Problem habe ich gesprochen. 8) Zitat:
Die
SQL-Code:
ist irgendwie anders bei MSSQL gelöst. Wenn ich so ein Statement schreibe kommt als Fehlermeldung, das
SELECT ... FOR UPDATE
die FOR..UPDATE Clausel nur in Verbindung mit Declare Cursor erlaubt ist. :?: Kennt jemand die genaue Verwendung der FOR UPDATE bei MSSQL :?: danke an alle Peter |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:31 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