Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Query Timeout expired

Begonnen von Stele4, April 17, 2025, 12:43:09

⏪ vorheriges - nächstes ⏩

Stele4

Hallo!
Auf eine einfache UPDATE-PathThrough-Abfrage in Access meldet der Treiber "... Query TimeOut expired...".

Zur Fehlereingrenzung wurde eine aehnliche Abfrage in SSMS ausgefuehrt:

use MyDb;
UPDATE tblGross
SET Dsc = Dsc + ' solala'
WHERE ID = 1;

Der Server ist lokal und die Tabelle nicht riesig.
Aber die Abfrage kommt nicht zum Abschluss.

Woran kann das liegen?

Gruss


PhilS

Zitat von: Stele4 am April 17, 2025, 12:43:09Zur Fehlereingrenzung wurde eine aehnliche Abfrage in SSMS ausgefuehrt:
Und?
Ich vermute, dabei gab es das Problem nicht?

Zitat von: Stele4 am April 17, 2025, 12:43:09Der Server ist lokal und die Tabelle nicht riesig.
Aber die Abfrage kommt nicht zum Abschluss.

Woran kann das liegen?
Wenn du in Access eine große Menge Datensätze anforderst, bleibt die entsprechende Tabelle gesperrt bis die Daten vollständig abgerufen wurden.

Ein Klassiker, der dieses Problem verursachen kann:
Du öffnest in Access in Formular, dass an eine Tabelle gebunden ist. Dabei werden nur die ersten X (genaue Zahl weiß ich gerade nicht) Datensätze abgerufen.
Wenn die Tabelle mehr Datensätze enthält, bleibt sie gesperrt, bis du im Access-Form an das Ende der Datensätze navigierst.
Falls du vorher ein Update auf diese Tabelle ausführst, warte der SQL Server bis die Sperre aufgehoben ist, oder bist der Timeout eintritt.

Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Stele4

Hallo Phil!
Das war wohl nicht eindeutig.

Die Aktionsabfrage in SSMS kommt nicht zum Schluss.
Hier gibt es wohl keine Zeitbgrenzung.

Eine SELECT-Abfrage wird sehr schnell ausgefuehrt. In Access und SSMS.

Gruss

PhilS

Zitat von: Stele4 am April 17, 2025, 12:57:36Die Aktionsabfrage in SSMS kommt nicht zum Schluss.
Wenn zur gleichen Zeit das/die Access-Formular(e) geöffnet sind, die, wie oben beschrieben, das Problem auslösen können, wäre das logisch.
Was passiert, wenn du Access komplett schließt und dann die Abfrage im SQL Server Management Studio ausführst?
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

markusxy

Zitat von: PhilS am April 17, 2025, 12:49:51Wenn die Tabelle mehr Datensätze enthält, bleibt sie gesperrt, bis du im Access-Form an das Ende der Datensätze navigierst.


Die Logik verstehe ich nicht.
Aus Server Sicht werden doch einfach eine bestimmte Anzahl Datensätze abgefragt und das wars.
Was verursacht den Lock?

OT: Persönlich verwende ich beim Server nur ADO, daher kann ich das Problem natürlich nicht haben.




Stele4

#5
Ich bin neu auf dem Feld und wuerde Markus zustimmen.
Doch Phil hat wohl wieder recht:

- Access-DB zu -> Abfrage in SSMS wird abgearbeitet.
- Access-DB auf -> auch ok
- Formular auf -> Problem

Die RecordSource des Formulars wird bei Form_Load per VBA geschrieben (als PathThrough-Abfrage).
OpenRecordset habe ich jetzt mit "Type:=dbOpenSnapshot" erweitert.
Das fuehrt aber nicht zum Erfolg.

Wie kann ich den Lock verhindern, wenn die ID (Autowert) in der Abfrage vorhanden sein muss?

Gruss


PhilS

Zitat von: markusxy am April 17, 2025, 13:56:19Die Logik verstehe ich nicht.

Aus Server Sicht werden doch einfach eine bestimmte Anzahl Datensätze abgefragt und das wars.
Was verursacht den Lock?
Das war's erst dann, wenn der Client auch alle Datensätze abgerufen hat.

Client1 sendet: SELECT * FROM EineTAb WHERE XYZ = 'irgendwas';
100 Datensätze entsprechen dem Kriterium. Der Client ruft aber erstmal nur 50 Datensätze ab.
Client2 sendet: UPDATE EineTAb SET XYZ = 'was anderes' WHERE XYZ = 'irgendwas';
Was soll der Server jetzt machen?
Dem Client1 auf Abruf dann die übrigen 50 DS geben, obwohl sie schon nicht mehr dem Kriterium entsprechen?
Gar keine Daten mehr zu der ursprünglichen Abfrage nachliefern, obwohl die UPDATE-Transaktion alle Datensätze betrifft, auch die bereits an den Client gesendeten?
Das wäre beides inkonsistent. Deshalb hält der Server die Sperre auf den vom ersten SELECT betroffenen Datensätzen, bis sie auch abgerufen wurden oder das Recordset des Selects geschlossen wurde.

Das Ganze lässt sich durch das Locking-Verhalten des Servers steuern, aber das kriege ich jetzt ad-hoc nicht belastbar zusammen.


Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

PhilS

Zitat von: Stele4 am April 17, 2025, 14:26:12Wie kann ich den Lock verhindern, wenn die ID (Autowert) in der Abfrage vorhanden sein muss?
Komplett verhindern kannst du den Lock nicht so ohne weiteres.
Du kannst aber dafür sorgen, dass Access schnellstmöglich alle Datensätze abruft und damit der Lock nicht mehr nötig ist.
Das geht mit: Recordset.MoveLast
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Bitsqueezer

Hallo,

sollte aber nur Formulare mit sehr vielen Datensätzen betreffen, da sich das Lazy Loading dann bemerkbar macht - und "MoveLast" bewirkt sofortiges Laden ohne Lazy Loading.

Ich würde aber auch mal in "Daten" im Formular die Einstellung "Datensätze sperren" überprüfen, im Allgemeinen ist es "Keine Sperrung" hier.

Pass-Through-Abfragen sind per Definition read-only, sollten also an sich ohnehin keine Sperrungen verursachen.
Du könntest aber versuchen, den NOLOCK-hint hinzuzufügen:
SELECT *
FROM yourSchema.yourTable (NOLOCK)

Gruß

Christian

PhilS

Zitat von: Bitsqueezer am April 17, 2025, 18:06:31sollte aber nur Formulare mit sehr vielen Datensätzen betreffen, [...]
"sehr viele" ist relativ. Ich denke bereits ab ca. 100 Datensätze kann dieser Effekt auftreten.

Zitat von: Bitsqueezer am April 17, 2025, 18:06:31Ich würde aber auch mal in "Daten" im Formular die Einstellung "Datensätze sperren" überprüfen, [...]
Das dürfte bei ODBC-Backends keine Auswirkung haben.

Zitat von: Bitsqueezer am April 17, 2025, 18:06:31Pass-Through-Abfragen sind per Definition read-only, sollten also an sich ohnehin keine Sperrungen verursachen.
Du könntest aber versuchen, den NOLOCK-hint hinzuzufügen:
Die Erläuterungen in #6 erklären implizit auch, warum read-only hier nicht relevant ist und warum NOLOCK i.d.R. keine gute Idee ist.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Bitsqueezer

Hallo,

bei 100 Datensätzen gibt es kein Lazy Loading... "MoveLast" bringt dann auch nichts. Denn die sind so schnell geladen, daß es keine Auswirkungen hat.

Da es um eine PT-Abfrage geht, die immer read-only ist, spielt es keine Rolle, wenn die Daten in der Zwischenzeit von z.B. einem anderen User geändert wurden. Die Daten können nicht verändert werden und zeigen daher möglicherweise nicht den aktuellsten Stand an - aber das ist in einer Multi-User-Datenbank auch zu erwarten. Was man mit einem einfachen "F5" beheben kann.

Gruß

Christian


Stele4

Meine Guete! Mir schwindelt.

Ich war davon ausgegangen, dass ein ReadOnly keine Sperre braucht.
Dabei hatte ich das stueckweise Nachladen ausser Acht gelassen.
Mein naechster Ansatz waere, mit Recordset.Open, ~.Clone und ~.Close die Sperre kurz zu halten.
Die Datensatzmanipulation dann wieder per PathThrough-Aktionsabfragen.

Bin gespannt.

Ich wuensche euch Frohe Ostern!
Dank und Gruss!

PhilS

Zitat von: Bitsqueezer am April 17, 2025, 22:14:00Denn die sind so schnell geladen, daß es keine Auswirkungen hat.
Bei den 100 Datensätzen mag ich grob falsch liegen. Es sind nur eben nicht so unfassbar viele Daten, die es braucht bis das Problem auftreten kann.
Wie lange es dauert ist sekundär. Der wesentliche Punkt ist ob/wann das vollständige Abrufen der Daten erfolgt.
Wenn du ein Form öffnest, das an eine ausreichend große Datensatzmenge gebunden ist, wird Access die Daten erst dann vollständig abrufen, wenn du ans Ende der Datensatzgruppe scrollst.

Zitat von: Bitsqueezer am April 17, 2025, 22:14:00Da es um eine PT-Abfrage geht, die immer read-only ist, spielt es keine Rolle, [...]
Während die Abfrage ausgeführt wird, muss der Server für einen konsistenten Zustand sorgen.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Bitsqueezer

Hallo,

wir reden über eine read-only-Abfrage, die also Daten nur anzeigen kann. Der Zustand durch eine konkurrierende Datenveränderung jeglicher Art ist vollkommen irrelevant. Es ist eine Momentaufnahme und als solche darf sie auch Daten zeigen, die vielleicht bereits während der Abfrage so nicht mehr existieren.

Hier ein wenig zum Selbstlesen:
https://www.sqlshack.com/understanding-impact-clr-strict-security-configuration-setting-sql-server-2017/

Zum Thema MoveLast hatte ich Dir bereits zugestimmt, nur nicht für 100 Datensätze. Keine Ahnung, warum Du das jetzt weiter diskutierst.

Gruß

Christian

Stele4

Hallo!
Die Quelle fuer das Formular wurde per VBA mit PT-Abfrage zugewiesen.
Danach war weder in Access noch in SSMS der Datensatz Nr. 1 schreibbar.
Also wurde versucht, die Datensatzquelle per Kopie zu trennen (s.u.).
Das funktioniert. Auch in Datensatz 8082.

Aber jetzt kann ich nicht mehr filtern!


Private Sub fbRequery()
'Datenquelle importieren und von Quelle trennen
Dim rst As DAO.Recordset

    Set rst = mdlx_Fct.fcSqlRst(sSql:="SELECT * FROM A_TagLst ORDER BY TagNr;")
    With rst
        .MoveLast
        Set Me.Recordset = .Clone
        .Close
    End With
       
    Me.Recalc
    Set rst = Nothing
   
End Sub