Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi FireDAC, onDemand, DeadLock (https://www.delphipraxis.net/196998-firedac-ondemand-deadlock.html)

haentschman 8. Jul 2018 11:10

Datenbank: MSSQL • Version: 2012 • Zugriff über: FireDAC

FireDAC, onDemand, DeadLock
 
Hallöle...:P
Heute brauche ich Hilfe...:roll:

Gegeben:

Anwendung mit 2Mio Zeilen und gewachsen... Nun stoßen wir mit dem Arbeitspeicher an die Grenze. Manche Forms greifen sich über 1GB Arbeitspeicher. Die Connection steht auf FetchMode fmAll und ReadCommited.
...aber sie läuft auch im Netzwerk problemlos. :?
Die EXE liegt auf einem Server für Alle.

Was ich gemacht habe:
Connection auf fmOnDemand mit 200 Datensätzen. Der Speicher hat sich auf 1/3 minimiert. Damit kann ich leben. Test lokal i.O.
Aber:
Im Netzwerk hatte ich zwischen 10 Minuten und 3 Stunden einen DeadLock mit einem INSERT
Statement. (leider habe ich keinen Screenshot) Desweiteren habe ich haufenweise Supended Pages. (im Prinzip logisch) Unabhängig von dem Statement habe ich den DeadLock!

Problem:

Die Anwendung ist permanent gestartet. Das läßt kaum Raum für Tests. :?

Was ich gelesen habe:

https://www.mcseboard.de/topic/20426...kierungen-aus/

Wie bekomme ich die Kuh vom Eis... :? Wie macht man es richtig mit den DataSets um DeadLocks vorzubeugen? Welche Voraussetzungen müssen für OnDemand gegeben sein? Sind SUSPENDED Pages "gefährlich"?

Ich hoffe auf den entscheidenden Tipp...:P

KodeZwerg 8. Jul 2018 11:24

AW: FireDAC, onDemand, DeadLock
 
SQL Server technical bulletin - How to resolve a deadlock Microsoft hilfestellungen, vielleicht ist etwas für Dein Problem enthalten?

HolgerX 8. Jul 2018 11:35

AW: FireDAC, onDemand, DeadLock
 
Hmm..

Schau Dir mal

https://docs.microsoft.com/de-de/sql...ql-server-2017

an und zwar das Thema 'SNAPSHOT'!

Hier wird bei jede Abfrage quasi der Instzustand (ohne aktuell laufende Transaktionen) ein Snapshot gemacht, auf den dein Query zugreift.
Dadurch werden keine Locks mehr bei selects gemacht und somit keine Deadlocks...

Hab das auch er vor kurzem entdeckt, jedoch noch nicht getestet...

haentschman 8. Jul 2018 12:11

AW: FireDAC, onDemand, DeadLock
 
Danke für Eure Zeit...:P
Aber ich denke, daß das ein Herumdocktern an den Symtomen statt einer Lösung ist.

Die Preisfrage ist doch, wer den Datensatz festhällt, obwohl Querys mit INSERT, EDIT und DELETE verwendt werden. Imho Imho kann eigentlich kein DeadLock
entstehen wenn alle umgehend ein Post ausführen. :gruebel: Wenn aber eine Query lange noch im Edit Mode steht kann es vorkommen, oder? Aber mit fmAll passiert es nicht. :gruebel:
Ich denke das das am Aufbau mit den Datasets bzw. deren Einstellungen liegt und nicht direkt mit dem Server. Der Server meckert dann aber...

Deshalb die Frage: Voraussetzungen fur FireDAC mit OnDemand...oder wie macht man es richtig.

Uwe Raabe 8. Jul 2018 13:04

AW: FireDAC, onDemand, DeadLock
 
Zitat:

Zitat von haentschman (Beitrag 1406747)
Aber mit fmAll passiert es nicht. :gruebel:

Bei fmAll werden alle Datensätze an den Client übertragen und der Cursor danach freigegeben. Daher kommt es in diesem Fall nicht zu einem Deadlock. Bei fmDemand bleibt der Cursor aber offen, damit die Next Calls auch klappen.

Ich würde es zunächst auch erstmal mit einem ckStatic Cursor versuchen. Der arbeitet auf einem temporären Snapshot und macht auch keine Locks. Das verlagert den Speicherbedarf allerdings auf den Server, aber der kann da in der Regel besser mit umgehen.

Es gilt aber zu beachten, daß auch bei fmDemand der lokale Speicher ziemlich anwachsen kann, wenn mit den Next-Calls dann doch alle Datensätze irgendwann im Speicher liegen. Dann hilft nur Unidirectional auf True zu setzen, damit der Speicher für die vorigen Datensätze auch gleich freigegeben wird. Sollte das nicht gehen, musst du dir ein Verfahren aussuchen, bei dem die Result-Sets kleiner werden.

haentschman 8. Jul 2018 13:38

AW: FireDAC, onDemand, DeadLock
 
Danke für die Info...:P
Zitat:

Sollte das nicht gehen, musst du dir ein Verfahren aussuchen, bei dem die Result-Sets kleiner werden.
...ist schon im Plan. Aber ich muß erst mal eine einigermaßen lauffähige Version schaffen um darauf aufzubauen. :zwinker:
Zitat:

Bei fmDemand bleibt der Cursor aber offen, damit die Next Calls auch klappen.
...das hatte ich auch so verstanden. Ich hatte aber gehofft, daß die FireDAC das irgendwie managen. (offener Cursor) :?
Zitat:

Ich würde es zunächst auch erstmal mit einem ckStatic Cursor versuchen. Der arbeitet auf einem temporären Snapshot und macht auch keine Locks.
...könntst du das noch mal genauer erklären? Was ist beim serverseitigem Cursor zu beachten?

Nachtrag:
Ich habe nun alle Cursor Versionen durch...das einzige was die Anwendung lädt: ckDefault(ckAutomatik) + fmAll aber mit großem Speicher. Alles mit serverseitigem Cursor kam mit "Invalid Cursor", beim Öffnen der Query :shock:, oder "ich mach dann mal nix mehr" mit SQL Eieruhr.

Alles ist nicht zufriedenstellend...:?

HolgerX 8. Jul 2018 15:47

AW: FireDAC, onDemand, DeadLock
 
Hmm..

Zitat:

Zitat von haentschman (Beitrag 1406747)
Die Preisfrage ist doch, wer den Datensatz festhällt, obwohl Querys mit INSERT, EDIT und DELETE verwendt werden. Imho Imho kann eigentlich kein DeadLock
entstehen wenn alle umgehend ein Post ausführen.

Nur ein kleiner Hinweis:
Der MS SQL-Server macht nicht nur für INSERT, EDIT und DELETE ein Row/Table Lock, sondern auch für SELECT.
Er entscheidet selber (je nach Query) ob er nur Rows, oder ganze Tables lockt.

Wenn dann irgend ein anderer Query ausgeführt wird, und dieser länger dauert kann es zu einem Deadlock kommen, wenn sich 2/3 oder mehr gegenseitig blockieren, wenn diese zu lange dauern und in den timeout gelaufen wird.
Hinweis: Ein Change ist nicht mit Post abgeschlossen, da diverse Aktionen wie Trigger/Index-Aktualisierungen auch noch danach laufen können.
Auch diese erzeugen wieder Locks..

Durch die möglichkeit von SNAPSHOT Verwendung werden alle Selects ohne Locks ausgeführt...

p80286 8. Jul 2018 21:50

AW: FireDAC, onDemand, DeadLock
 
Und da gibt es Leute, die sagen MSSQL ist keine richtige Datenbank.:mrgreen:

Aber im Ernst,
SQL-Code:
Select * from ...
hast Du nicht verwendet?
Schau Dir unbedingt mal https://docs.microsoft.com/en-us/sql...ql-server-2017 an.
Worauf setzt Firedac denn auf?
ODBC war (oder ist) ein wenig komplex, es gab/gibt die Möglichkeit die Query-Ergebnisse mit einem ODBC-Cursor zu verwalten, was aber einen enormen Speicherhunger nach sich zog. Ggf. gibt es da für Dich einen Ansatzpunkt.


Gruß
K-H

haentschman 9. Jul 2018 06:07

AW: FireDAC, onDemand, DeadLock
 
Moin...:P
Zitat:

Durch die möglichkeit von SNAPSHOT Verwendung werden alle Selects ohne Locks ausgeführt...
Wie stelle ich das in FireDAC ein?
Zitat:

Aber im Ernst, Select * from ... hast Du nicht verwendet?
...da gibt es reichlich. :?

Nochmal: Wir reden über 2Mio Zeilen. Ich bin erst seit einem halben Jahr dabei. Es gibt Bereiche die ich noch nichtmal angefaßt habe. Ich muß nun die Kuh vom Eis kriegen. Mit jeder Rechnung steigt der Arbeitsspeicher. Ich kann aber nicht eben mal das bestehende Konzept auseinanderreißen. :? Daß ich das tun muß ist klar...wie macht das am lebenden Patienten?

Ich bräuchte eine funktionierende Konstellation in Stichpunkten:
1. Server mit Einstellung Blubb
2. Connection mit Einstellung Bla
3. Was ist bei den Querys zu beachten
4. Wie verhalten sich INSERTS die direkt in die Tabelle schreiben
... usw. :wink:

HolgerX 9. Jul 2018 07:56

AW: FireDAC, onDemand, DeadLock
 
Hmm..

Zitat:

Zitat von haentschman (Beitrag 1406758)
Moin...:P
Zitat:

Durch die möglichkeit von SNAPSHOT Verwendung werden alle Selects ohne Locks ausgeführt...
Wie stelle ich das in FireDAC ein?

Gar nicht!

Das ist eine Einstellung auf dem SQL-Server!
Dieser regelt dann die Snapshot-Geschichte, da dieser auch die Locks ausführt.

Schau Dir bitte den Link an, dort sind die Transact-SQL Befehle für das setzen des Isolationslevel erklärt. Ich hatte noch per Google andere Info-Quellen gefunden.
Die Konfiguration für SNAPSHOT kann für die gesamte Datenbank global gesetzt werden, es gibt jedoch auch die Möglichkeit dies nur für einen Query zu machen.

Wenn du es global setzt, ist es gleich, wie Du auf den SQL-Server zugreifst und es bedarf keiner Änderungen in deinem Programm.

Alternativ könntest Du auch jeden Select-Query änderen und dort z.B. WITH NOLOCK eintragen ;)

Hier noch einen Link:
https://docs.microsoft.com/de-de/dot...-in-sql-server


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:49 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz