TADOQuery und TADOConnection

    TADOQuery und TADOConnection

    Hallo an alle,


    ich suche vergebens nach einer Lösung einer Verständnisfrage.

    Nutze das Delphi 10 Seattle.

    Habe nun ein Programm gebaut, welches mit einem ReadOnly-Recht Daten aus einer Datenbank ausliest und neu darstellt.


    Nutze dazu TADOquerys .... brauch man bei ReadOnly eine TADOConnection? Ich kann den String auch direkt in die Queries schreiben! Muss man das machen? Was ist der Vor- und Nachteil.


    Ich bekomme einmal in der Woche ein DeadLock Victim, welcher nicht kommen darf, da es eine Anzeige für Patienten ist. Liegt das dadran, dass ich bei Start des Programms die ADOConnection.connected auf True setze und erst beim Beenden wieder auf False.


    Die Queries werden erst aktiv wenn die Abfrage erfolgt und werden direkt danach geschlossen.


    Ich danke für veständnisvolle Antworten
    Hallöle... 8o
    Ich bekomme einmal in der Woche ein DeadLock Victim, welcher nicht kommen darf, da es eine Anzeige für Patienten ist.

    ...das verstehe ich nicht. Bitte definiere die Fehlermeldung. :whistling:

    Eine Connection brauchtst du immer. Ob normal oder ReadOnly.

    Liegt das dadran, dass ich bei Start des Programms die ADOConnection.connected auf True setze und erst beim Beenden wieder auf False.

    Solange du die Connection im Objektinspector nicht auf True setzt, dann ist alles gut.

    Die Queries werden erst aktiv wenn die Abfrage erfolgt und werden direkt danach geschlossen.

    ADO hat so seine Eigenheiten. Fehler die keine sind, oder sich schwer nachvollziehen lassen. :/

    Fazit aus eigener Erfahrung:
    ADO austauschen. Wenn es die Finanzen zulassen...UniDAC! Dann sind die "sporadischen" Fehler Geschichte.

    Ich kann den String auch direkt in die Queries schreiben! Muss man das machen? Was ist der Vor- und Nachteil.

    Mit mir hast du den richtigen gefunden. Ich bin ein leidenschaftlicher Verfechter der SQL Statments außerhalb vom Quelltext. :thumbup:
    Persönlich hast du die Wahl...

    Statements in Query (in der Komponente):
    + leicht einzutragen
    - Suche nach einen Statement fast unmöglich
    - Statement wird in der DFM gespeichert. Im Versionskontrollsystem ist immer die DFM einer Form geändert...nicht gut.
    - Datenbankunabhängigkeit unmöglich
    usw.

    PS: Welches DBMS?

    8o

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „haentschman“ ()

    Servus haentschman,

    Komisch ist, dass ich bei TADOQuery einen ConnectionString einfügen kann und damit ohne TADOConnection auskomme .... Meine Frage ist, was ist VOr- und NAchteil von beiden Wegen (Connection auf TADOConnection setzen oder ConnectionString).

    Leider kann ich keine neuen Komponenten nutzen, da ich finanziell durch das Projekt ausgezerrt bin (Hardware, Anbau usw.)

    DBMS ist Microsoft SQL-Server

    Der DeadLock Victim war eigentlich als Nebeninfo gedacht, da ich hoffe jeamnd sagt, das liegt an dem und dem Problem.

    Fehlermeldung "Transaction (Process ID 96) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction"

    Kann es sein, dass während einer Query-Abfrage, eine weitere BAfrage die Daten (Tables) nutzt und es deswegen zu dem Fehler kommt? kann man vorher den Fehler abfangen durch eine ABfrage?
    Kann es sein, dass während einer Query-Abfrage, eine weitere BAfrage die Daten (Tables) nutzt und es deswegen zu dem Fehler kommt?

    ...genau so sieht es aus. :/

    kann man vorher den Fehler abfangen durch eine ABfrage?

    Nicht wirklich. Im Fehlerfalle würde ich die Query schließen und neu öffnen. Dann sollte das wieder gehen. (Damit habe ich so meine Erfahrungen... ;( )

    Komisch ist, dass ich bei TADOQuery einen ConnectionString einfügen kann und damit ohne TADOConnection auskomme

    Grundsätzlich brauchst du eine Connection. Ob auf dem Datenmodul oder, wahrscheinlich, automatisch von der Query im Backend erzeugt. Es macht keinen Unterschied.

    Idee:
    Wenn die Daten es zulassen...die Daten in Datenobjekte konvertieren. Das bedeutet, die Query ist nur kurz auf und wieder zu. Der Rest des Programmes arbeitet "offline" mit den Objekten.
    Fertsch... 8o
    Tutorial zu der Idee:
    delphipraxis.net/193418-%5Btut…alisierten-datenbank.html

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „haentschman“ ()

    Hallo haentschman,

    Ok vielen Dank, Ich dachte erst (ohne den Fehler zu sehen), dass es vll daran liegt, dass die DB nicht erreicht werden kann. Ich habe insgesamt 5 Queries die untershcieldiche Daten Abgfragen und zumeist voneinander abhängig sind. zeitgleich läuft ein Timer, welcher nachschaut, ob die Daten noch aktuell sind. Ich glaube, dass es da zu Überschneidungen kommt. Eventuell muss ich im Timer vor der SQL-Abfrage nachschauen ob die 4 anderen Queries zu sind oder? Dann dürfte ja nichts passieren oder?

    Ich danke dir, du hast mir echt viel geholfen!
    Grundsätzlich sollte eine Query (auch AdoQuery) keine Lockings erzeugen. Zunächst liest eine Query (wenn es sich um ein Select-Statement handelt) nur die Daten auf dem SQL Server aus und stellt sie in einem DataSet zur Verfügung.

    Das Locking kann eigentlich nur von einer Transaktion stammen, die die Page gesperrt hat, auf die du mit einer Query zugreifen willst. Das muss nicht aus deinem Programm geschehen sein. Es kann z.B. der SQL Server selbst sein - z.B. ein Wartungslauf, eine Datensicherung.

    Ich stelle mir aber jetzt zunächst mal die Frage, warum du die Aktualisierung der Queries über einen Timer triggerst. Sollte das nicht besser gezielt vom Anwender erledigt werden (über einen Aktualisierungsbutton)? Wie realisierst du die Aktualisierung?

    Grüße
    Mikhal
    Computer erleichtern die Arbeit -
    und die Welt ist eine Scheibe!
    Hallo haentschman

    Von deiner Seite her...ja. Wenn aber ein anderer User die gleiche Tabelle beschreibt, hast du wieder das gleiche Problem.


    Gilt dies nur für das beschreiben oder auch auslesen, ich lese nicht aus, ich suche nur Informationen und verarbeite sie in meinem Programm


    Hallo Mikhal,

    wenn ich erzähle was ich vor habe, dann schlägst du wahrscheinlich die Händer über dem Kopf zusammen.

    Also mal zum Standpunkt.

    Ich arbeite in einer Strahlentherapie, bin beruflich Medizinphysiker und programmiere nebenbei.

    Da im Februar 2018 spätestens ein neues Gesetz kommen muss, wo nicht nur Risikomanagement vorkommt sondern auch Gefahrenmanagement, muss in der Strahlentherapie ein Problem angegangen werden.

    Und zwar die Patientenverifikation vor der Bestrahlung. Es kommt leider ab und zu mal vor, dass man Herrn Meyer aufruft und Herr Schulze in die Umkleidekabine läuft, weil er meint, er wartet länger und will bestrahlt werden. Die MTRA´s überprüfen das zwar, aber doch kann es vorkommen, dass ein Patient durchhuscht (Schichtwechsel, erste RT oder sonstiges).

    Um dieses große Risiko zu minimieren, habe ich vor den "Bunker" ein Touch-Bildschirm aufgebaut. Dies soll der Patient berühren, dann erscheint sein ID-Foto und er muss sich selber verifizieren. Danach kommen noch weitere Infos zu seinem nächsten Termin, wie weit er in der Behandlung ist und eventuelle Informationen zu Wartung oder Quartalswechsel (neue Überweisung nötig).

    Ich kann nicht direkt auf den Linearbeschleuniger zugreifen, was auch richtig ist. Aber das ROKIS (RadioOnkologieKrankenhausInforamtionsSystem) gibt mir die Chance, über den Terminkalender des Linearbeschleunigers zu sehen, welcher Patient aktuell aufgerufen wurde an der Bestrahlungskonsole.

    Damit nach Beendigung der RT nun der nächste Patient verifiziert werden kann, muss ich abfragen welcher Patient (nur den PatientenKey) geladen ist und gleiche im Programm ab.

    Deswegen nutze ich den Timer, um jede Sekunde die Daten abzugleichen.

    Da die Datenbank ein Teilsystem des ROKIS ist und damit CE-zertifiziert und nach MedizinprodukteGesetz zu sehen, habe ich nur ReadOnly-rechte genutzt.

    Gäbe es eine elegantere Lösung, um zu sehen, ob sich was geändert hat?
    Der Patient ruft doch bereits seine Daten mit dem Berühren des Touch-Screens ab, an dieser Stelle solltest du die Query abfeuern, dann hast du die aktuellsten Daten.

    Aber es klingt für mich so, als wolltest du permanent den gesamten Datenbestand des Tages vorhalten. Das ist Kontraproduktiv und kann am ehesten dazu führen, dass deine Abfrage geblockt wird. Frage an dieser Stelle am besten nur die "Patienten-Daten" eines kleinen Zeitraums ab, z.B. die Termine eine halbe Stunde rund um den Abfragetermin ab - also 1/2 Stunde vor und eine 1/2 Stunde nach dem Abrufzeitraum, zeige nur die Daten an, die aktuell gültig sind.

    Eine Frage bleibt noch offen: Arbeitest du selbst in einer Transaktion? Wenn ja, solltest du die Daten direkt in einen Container kopieren, mit dem du weiterarbeitest. Da böte sich zum Beispiel TVirtualTable oder TVirtualDataSet an, um die Daten zu bunkern, wenn du datensensitive Komponenten verwendest. Nach dem Kopieren, musst du die Transaktion beenden, damit es zu keinem weiteren Konflikt kommt.

    Grüße
    Mikhal
    Computer erleichtern die Arbeit -
    und die Welt ist eine Scheibe!
    Hallo Mikhal,


    Ich habe eine TADOConnection, welche bei Starten des Programmes die Verbindung aufnimm und bei schliessen des Programmes beendet wird.

    Wenn der Patient den Bildschirm berührt, wird abgefragt welcher Patient an der Behandlungskonsole geöffnet ist .... der Status ist bei diesem Patient (Termin gebunden an Patient) auf 'in Progress' gesetzt. Ich frage nur nach dem Status.

    ICh übergebe direkt die Paramete, setze Query_active :=True, nehme mir die Daten, welche ich brauche (Foto) und schliesse das Query wieder.

    Habe jetzt den Timer (meine Aktualisierung) so umgestellt, dass er erst eine Verbindung aufbaut, wenn alle Queries geschlossen sind. Smoit dürfte dort kein Deadlock Victim kommen.

    Spassig wird es, wenn die Software an 4 unterschiedlichen Linearbeschleuniger läuft, da alle die gleichen Abfragen haben, nur der Parameter Linac ändert sich.
    Spassig wird es, wenn die Software an 4 unterschiedlichen Linearbeschleuniger läuft, da alle die gleichen Abfragen haben, nur der Parameter Linac ändert sich.

    Eigentlich sollte das kein Problem sein, das sollte ein SQL Server ab können. Ich arbeite in einem produzierenden Gewerbe mit eigenem Vertrieb, da ist es an der Tagesordnung, dass mehrere Benutzer auf die gleichen Daten zugreifen. Und das ohne Probleme. Gut, unser SQL Server wird nicht so stark frequentiert, aber auch hier gibt es höchstens einen Programmhinweis, dass der Datensatz durch einen anderen Benutzer geblockt ist und man nur lesend zugreifen kann.

    Mir ist deine Fehlermeldung auch noch nie begegnet, ich kenne nur das Pending, wenn eine Page durch eine andere Transaktion geblockt ist, was immer wieder vorkommt, aber sich selbst auflöst, weil Transaktion sehr kurz gefasst sind.

    Grüße
    Mikhal
    Computer erleichtern die Arbeit -
    und die Welt ist eine Scheibe!

    Ozoras schrieb:


    Um dieses große Risiko zu minimieren, habe ich vor den "Bunker" ein Touch-Bildschirm aufgebaut. Dies soll der Patient berühren, dann erscheint sein ID-Foto und er muss sich selber verifizieren. Danach kommen noch weitere Infos zu seinem nächsten Termin, wie weit er in der Behandlung ist und eventuelle Informationen zu Wartung oder Quartalswechsel (neue Überweisung nötig).

    Wie verifiziert sich derjenige denn? Einfach nur durch Bestätigung, dass er derjenige ist, dessen Bild er sieht? Das wäre ungut, gerade wenn ihm danach persönliche Daten angezeigt werden. Das wäre dann nicht im Sinne des Datenschutzes.
    Gruß Thomas

    Admin werden ist nicht schwer, sein ......
    Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
    Hallo Mikhal,


    vielen Dank für die Infos. Ich schaue einfach, was nun daraus wird


    Hallo Thomas,

    gerade wegen dem Datenschutz wird nur das Bild angezeigt.

    Wenn er bestätigt, dass er es wirklich ist, wird sein Nachname angezeigt (Intro "Hallo Herr Meyer")
    Dann kommt der Stand seiner Therapie (X % der Therapie schon abgeschlossen) und sein nächster Termin wird angezeigt


    Das ist erst Version 1.0. Wir wollen irgendwann über RFID-Karten den Patienten verifizieren und falls die Karte vergessen wurde, dann über Foto.
    Die RFID ist da schon eine gute Lösung. Ansonsten wüßte ich nicht, was Herrn Schulz daran hindern sollte, das Bild von Frau Meyer zu bestätigen und danach deren Daten abzulesen.
    Gruß Thomas

    Admin werden ist nicht schwer, sein ......
    Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
    SQL-Server?
    Dann lese die Daten doch mit "WITH (NOLOCK)" ... liest zwar dann auch die 'uncommitted', aber das dürfte in Deinem Fall weniger kritisch sein
    mssqltips.com/sqlservertip/247…e-sql-server-nolock-hint/
    "After three days without programming, life becomes meaningless." (The Tao of Programming, Book 2)
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand" (Martin Fowler, 'Refactoring')
    Hallo Thomas,

    Wir haben uns einfach erstmal eine einfache Version für InHouse gesucht. Na klar kann Herr SChulz die Daten auslesen, aber er müsste dann auch für Frau Meyer bestrahlt werden. Das ist ja kein InfoTerminal sondern eine Patientenverifikation vor der Bestrahlung. Wenn ein Patient grobfahrlässig handelt, können wir auch nichts mehr unternehmen. Spätestens am Tisch, wenn eine Mamma (Brust) bestrahlt werden soll, aber die Markierungen im Beckenbereich sind, würde das erneut auffallen.

    Wenn wir durch das kleine Projekt den ZUschlag bekommen, werden wir 100% auf RFID gehen. Aktuell mussten wir damit nur zeigen, dass wir das Können und wollen. Und wenn schon was zu sehen ist, was auch funktioniert, dann ist die Entscheidung für die Geldgeber einfach viel einfacher.

    Hallo BerndG,


    Das ist haargenau das Problem. Ich danke.


    Habe einige DB-Analysen durchgelaufen und siehe da, ich fighte mit dem Linearbeschleuniger. Er lockt den BEreich, weil er die Bestrahlungsdaten zurück schreibt. Um eine 100% Rückschreibung zu gewährleisten, wird der komplette Patient gelockt. Wäre auch doof, wenn auf einmal eine Bestrahlung fehlt.


    Mit dem "WITH (NOLOCK)" umgehe ich das, da ich die Daten sowieso nicht manipuliere, sondern nur auslese.


    Ich danke vielmals allen, die hier kommentiert haben, Ihr habt die Qualitätssicherung in der Strahlentherapie damit ein Stück sicherer gemacht!
    @Ozoras: Was ich Dir hier aufzeigen wollte, war nicht, dass der Patient die falsche Behandlung bekommt, wenn er so dämlich ist, das falsche Bild zu bestätigen.
    Was ich aufzeigen wollte ist, das ein Patient bewußt das falsche Bild bestätigen könnte, um an die Daten des anderen Patienten zu kommen. Diese Möglichkeit darf aus datenschutzrechtlicher Sicht nicht gegeben sein.
    Auch das dürfte für den Kunden durchaus relevant sein.
    Gruß Thomas

    Admin werden ist nicht schwer, sein ......
    Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
    Hallo Thomas,

    Ich danke dir, das Thema Datenschutz ist bei uns auch das große Thema gewesen.
    ich weiss, dass wir mit der aktuellen Version gegen das Datenschutzgesetz verstossen, da wir einen ungeschützten Zugang zu fremden Patientendaten bieten.

    Aber da wir dies in einem gesperrten Bereich unter Aufsicht aktuell gestalten, ist dies ein Risiko, welches aber minimiert wird. Und dadurch zwar nicht ganz akzeptiert aber tolleriert wird. Genauso könnte ein Patient an die BEstrahlungskonsole gehen und sieht dort weitaus mehr Informationen.

    Bei uns sieht er nur den Nachnamen, den Status der Behandlung (also XX% von 100% erreicht) und den nächsten Termin. An der Behandlungskonsole sieht man Zielvolumen, Diagnose und vieles mehr. Hier kann der Datenschutz aufgrund therapeutischer Notwendigkeit nicht eingehalten werden. Auch ist dort eine Patientenliste mit vollen Vor-und Nachnamen.


    Wir gehen aktuell einfach davon aus, dass dies ein gesperrter Bereich ist und nur unter AUfsicht betreten werden kann. Alleine der Strahlenschutz gibt uns hier die notwendige Befugnis.


    Aber danke, dass du so aktiv mitdenkst, das freut mich sehr.