![]() |
Datenbank: MSSQL • Version: 2017 • Zugriff über: FireDAC
Deadlockopfer bei TDataset.Refresh
Liste der Anhänge anzeigen (Anzahl: 1)
Hallöle...8-)
Wie kann ein lesender "Vorgang" (Refresh) einen Deadlock auslösen? :gruebel: Habe ich was verpaßt? :wink: Ist das wieder ein MSSQL Ding? Info: laufende Replikation Danke |
AW: Deadlockopfer bei TDataset.Refresh
Was macht das DataSet?
|
AW: Deadlockopfer bei TDataset.Refresh
An einem Deadlock sind zwei Transaktionen beteiligt. Das Lesen ist nicht mehr erlaubt, da die Daten zwischenzeitlich geändert wurden ...
(so interpretiere ich die Meldung) |
AW: Deadlockopfer bei TDataset.Refresh
Zitat:
Delphi-Quellcode:
Hilft "CanRefresh" da weiter? Die Hilfe dazu ist dürftig. Ich hoffe, daß das das macht was draufsteht. :wink:
procedure TDMED.FDQAdrAfterPost(DataSet: TDataSet);
begin dmRepositories.EdRepoExtLookupAdr.Properties.DataController.DataSet.Refresh; end;
Delphi-Quellcode:
procedure TDMED.FDQAdrAfterPost(DataSet: TDataSet);
var Data: TDataSet; begin Data := dmRepositories.EdRepoExtLookupAdr.Properties.DataController.DataSet; if Data.CanRefresh then begin Data.Refresh; end; end; |
AW: Deadlockopfer bei TDataset.Refresh
Sicher, dass es nicht das "Post" davor ist, dass den Deadlock auslöst?
|
AW: Deadlockopfer bei TDataset.Refresh
Der MSSQL Server lockt beim Lesen. Je nach zu lesender Datenmenge, Last am Server etc kann das Locking von einem Row Lock bis zu einem Table Lock eskalieren (lock escalation).
Das hat mit Transaktionen beim Schreiben nochnicht mal was zu tun. ![]() ![]() |
AW: Deadlockopfer bei TDataset.Refresh
Lock Escalation ist ziemlich ätzend bei MSSQL. Aber man muss sagen, das geschieht nicht aus Spaß oder gar Boshaftigkeit, sondern in "Notlagen".
Wenn Lock Escalation eintritt, würde man dem Server wohl anmerken, dass er "Atemnot" hat (außer er ist gut aus dem Blick weg virtualisiert) Ein Refresh würde m.E. auch kein Lock verursachen oder auslösen, eher würde ein Wait stattfinden, bis commitete Daten vorliegen. (aber ich hab damit schon ewig nichts mehr gemacht, also unsicher) Frage wäre, ob das Refresh ein (interner) Teil eines Post ist. Es gibt ja diese Mechnismen, die nachschauen, ob noch alles seine Ordnung hat. Also vor dem wirklichen Post vergleichen, ob die Daten, die vor dem Edit geholt wurden, auch noch so vorhanden sind. (Damit nicht die Änderungen eines anderen überschrieben werden, ohne dass es bemerkt wird.) Die SQL Variante davon ist in D oder anderen Umgebungen sowas wie: Update <meineTabelle> set <irgendwelcheFelder> = <irgendwelcheWert> where id=<schlüsselwert> and <alleFelder>=<alleVorigenWerte> |
AW: Deadlockopfer bei TDataset.Refresh
Beim MS SQL Server muss man auf DB-Ebene die richtige Einstellung machen, damit er nicht bescheuerte Locks beim Lesen setzt.
Geht seit der 7er Version, ist aber Standardmäßig deaktiviert. |
AW: Deadlockopfer bei TDataset.Refresh
Danke für die vielen Infos...:thumb:
Zitat:
Zitat:
Zitat:
|
AW: Deadlockopfer bei TDataset.Refresh
Zitat:
|
AW: Deadlockopfer bei TDataset.Refresh
Zitat:
Code:
...ist das eine Möglichkeit?
SET LOCK_TIMEOUT
Nachtrag: mal auf 1000 gesetzt. Warten wir auf den nächsten Fehler...:stupid: |
AW: Deadlockopfer bei TDataset.Refresh
So ein Zufall: heute ist mir dieser "Deadlockopfer"-Fall (ebenfalls MS SQL) begegnet.
Code:
bzw.
Die Transaktion (Prozess-ID 790) befand sich auf Sperre Ressourcen aufgrund eines anderen Prozesses in einer Deadlocksituation und wurde als Deadlockopfer ausgewählt. Führen Sie die Transaktion erneut aus.
Code:
Danke an die Beitragenden, eventuell kann ich später auch etwas beisteuern.
Die Transaktion (Prozess-ID 871) befand sich auf Sperre | Kommunikationspuffer Ressourcen aufgrund eines anderen Prozesses in einer Deadlocksituation und wurde als Deadlockopfer ausgewählt. Führen Sie die Transaktion erneut aus.; nested exception is java.sql.SQLException: Die Transaktion (Prozess-ID 871) befand sich auf Sperre | Kommunikationspuffer Ressourcen aufgrund eines anderen Prozesses in einer Deadlocksituation und wurde als Deadlockopfer ausgewählt. Führen Sie die Transaktion erneut aus.
|
AW: Deadlockopfer bei TDataset.Refresh
Moin...8-)
Update:
Delphi-Quellcode:
...hat nicht funktioniert. :?
procedure TDMED.FDQAdrAfterPost(DataSet: TDataSet);
var Data: TDataSet; begin Data := dmRepositories.EdRepoExtLookupAdr.Properties.DataController.DataSet; if Data.CanRefresh then begin Data.Refresh; end; end;
Delphi-Quellcode:
...das hat bis dato keinen Deadlock mehr ausgelöst. :thumb:
procedure TDMED.FDQAdrAfterPost(DataSet: TDataSet);
begin repeat Sleep(100); until not TFDQuery(DataSet).Connection.InTransaction; dmRepositories.EdRepoExtLookupAdr.Properties.DataController.DataSet.Refresh; end; Da ich das an mehreren Stellen habe mache ich mir eine function in meinen Tools...:thumb: |
AW: Deadlockopfer bei TDataset.Refresh
Dann solltest du aber kein BeginTransaction in deinem Code haben, weil dann dieser Code hängen bleibt, weil diese Tansaction nicht nach dem Post automatisch beendet wird.
|
AW: Deadlockopfer bei TDataset.Refresh
Moin...
genervte Grüße...:? Kaum redet man drüber geht es nicht mehr. Zitat:
Zitat:
Logisch...:zwinker: Ich habe noch eine Abbruchbedingung mit drin...(Anzahl Versuche) |
AW: Deadlockopfer bei TDataset.Refresh
wie rausfinden, wer noch läuft und an wem es dann wohl hängen könnte:
![]() |
AW: Deadlockopfer bei TDataset.Refresh
Zitat:
Und vielleicht hilft das auch: ![]() |
AW: Deadlockopfer bei TDataset.Refresh
Zitat:
...ist mir eigentlich egal. Ich brauche eine Prüfung ob das Refresh ausgeführt werden kann. :? Was ich probiert habe: Query.Connection.InTransaction Connection.InTransaction (was imho das gleiche ist) Query.CanRefresh Welche Möglichkeiten habe ich noch? PS: Das ist erst, seit ich das automatische Aktualisieren der Oberfäche eingebaut habe. Dadurch hat die Häufigkeit der Ausführung des Refresh deutlich zugenommen. :roll: Zitat:
Trotzdem Danke. |
AW: Deadlockopfer bei TDataset.Refresh
Das hat mit Transaktionen nur bedingt zu tun. Dein Problem sind LOCKs + die werden auch durch bloßes Lesen erzeugt. Die Locks können neben einzelnen ROWs auch ganze Seiten oder Tabellen umfassen + damit Sätze sperren, die mit der aktuellen Abfrage gar nichts zu tun haben. Siehe weiter vorne im Thread.
|
AW: Deadlockopfer bei TDataset.Refresh
Zitat:
Ich kann um das Refresh einen leeren try/except Block machen. :duck: |
AW: Deadlockopfer bei TDataset.Refresh
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:56 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