Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Firebird client application wait for row to unlock

My familiarity is with the Microsoft SQL server world using ADO (dbGo), and I have written many applications for that environment. Now I have a legacy Delphi 7 application with a Firebird 2.5 database that I must maintain.

BUT I am finding is that if 2 client applications execute this:

SQLQuery.SQL.Text := 'Update mytable set field1 = 11 where keyfield = 99'
SQLQuery.Execute;

at nearly exactly the same time, the 2nd application gets a "deadlock" error immediately. In SQL Server, there would be a wait period

ADOConnection.Isolationlevel = ilCursorstability;
ADOConnection.CommandTimeout := 5;

before any exception is raised in the second client app. The exception handling might involve a rollback in what would be deemed as a very unusual situation within a batch process. This is reasonable. 5 seconds is an awfully long time in computer processing time.

Now my attempts at using the same methodology at the Firebird Client have been fruitless because the "deadlock" (actually, a record in use) occurs immediately.

If the database engine can't be configured to wait a little for conditions to improve (record locks to be released), the responsibility must now rest with the client application developer who must write insanely slow code to overcome what appears to me to be major failing of Firebird.

Once the "deadlock" has been detected, the condition doesn't clear except by disconnecting the connection component

while rowsupdated = 0 and counter < 5 do
begin
  try
    rowsupdated := SQLQuery.Execute;
  except
    SQLConnection.Connected := False;
    SQLConnection.Connected := True;
  end;
  Inc(Counter)
end;

How do you make robust multi-user table-update clients when you don't have any substantial lock tolerance in Firebird, using DBX in Delphi?

like image 808
Freddie Bell Avatar asked May 21 '15 16:05

Freddie Bell


1 Answers

The client can specify if the transaction should wait for deadlock resolution. If in your case the deadlock happens immediately it's probably because of your configuration (using nowait transaction parameter on the client). Not using nowait will cause the server side to detect a deadlock and (after a configurable timeout) raise an exception on the client.

Since Firebird 2.0 you can also specify a lock timeout on a transaction from the client, overriding the server-configured timeout value.

like image 69
Ondrej Kelle Avatar answered Sep 24 '22 10:09

Ondrej Kelle