Meine Vertrautheit ist mit der Microsoft SQL-Server-Welt mit ADO (dbGo), und ich habe viele Anwendungen für diese Umgebung geschrieben. Jetzt habe ich eine ältere Delphi 7-Anwendung mit einer Firebird 2.5-Datenbank, die ich pflegen muss.Wie Firebird Client-Anwendung warten auf Zeile zum entsperren
aber ich bin zu finden, ist, dass, wenn 2-Client-Anwendungen ausführen dieses:
SQLQuery.SQL.Text := 'Update mytable set field1 = 11 where keyfield = 99'
SQLQuery.Execute;
bei fast genau die gleiche Zeit, die zweite Anwendung sofort ein „Deadlock“ Fehler bekommt. In SQL Server gibt es eine Wartezeit
ADOConnection.Isolationlevel = ilCursorstability;
ADOConnection.CommandTimeout := 5;
bevor jede Ausnahme in der zweiten Clientanwendung ausgelöst wird. Die Ausnahmebehandlung kann einen Rollback in einer Situation enthalten, die in einem Stapelprozess als sehr ungewöhnlich angesehen wird. Dies ist vernünftig. 5 Sekunden sind eine schrecklich lange Zeit in der Computerverarbeitungszeit.
Jetzt sind meine Versuche, die gleiche Methodik beim Firebird Client zu verwenden, erfolglos, weil der "Deadlock" (eigentlich ein Datensatz in Verwendung) sofort auftritt. Wenn das Datenbankmodul nicht so konfiguriert werden kann, dass es auf Zustände zur Verbesserung wartet (Sperren von Datensätzen wird freigegeben), muss die Verantwortung nun beim Entwickler der Clientanwendung liegen, der wahnsinnig langsamen Code schreiben muss, um das zu beseitigen, was zu erscheinen scheint Ich bin ein großer Fehler von Firebird.
Sobald die „Deadlock“ erkannt wurde, hat die Bedingung nicht klar, außer durch die Verbindungskomponente trennen
while rowsupdated = 0 and counter < 5 do
begin
try
rowsupdated := SQLQuery.Execute;
except
SQLConnection.Connected := False;
SQLConnection.Connected := True;
end;
Inc(Counter)
end;
Wie stellen Sie robuste Multi-User-Table-Update-Clients, wenn Sie nicht haben, jede wesentliche Lock-Toleranz in Firebird, mit DBX in Delphi?
Haben Sie FirebirdSQL schon länger nicht mehr verwendet, aber denken Sie daran, dass es eine Funktion SELECT UPDATE WITH LOCK gab, die stattdessen auf SQL-Ebene verwendet werden konnte. Überprüfen Sie dies: http://www.firebirdsql.org/refdocs/langrefupd25-notes-withlock.html – quasoft
Der Standardwert für den IsolationLevel für eine DBExpress-Verbindung zu Interbase ist 'ReadCommitted', was" ilCursorstabilität "entspricht. Das 'CommandTImeout' existiert nicht, aber es gibt' WaitOnLocks', das standardmäßig auf 'True' steht und bedeutet * Gibt an, dass eine Transaktion auf den Zugriff wartet, wenn sie einen Sperrkonflikt mit einer anderen Transaktion * (gemäß den Dokumenten) feststellt. Beide sind in den Verbindungsparametern festgelegt. –
Trotz all meiner Versuche, den Client anders zu konfigurieren, scheint er standardmäßig 'nowait' zu sein. Siehe meine Frage zu @TOndrej unten. – nolaspeaker