Search code examples
lockingfirebirdfirebird-3.0

Differences in "procedure locking" based on the way the client is connecting to the database


I have created a test procedure like that:

CREATE OR ALTER PROCEDURE tmp_fab
RETURNS (dummy INTEGER) AS
BEGIN
    dummy = 1;
    suspend;
END

Then a first client ("client A") uses the procedure by executing the following SQL:

SELECT *
FROM tmp_fab

If another client ("client B") tries to alter the procedure (while the "client A" transaction is still active and not committed/rolledback), I see a different behaviour based on the way the "client B" is connecting to the database.

For example:

Trying to alter the procedure as follows:

CREATE OR ALTER PROCEDURE tmp_fab
RETURNS (dummy INTEGER) AS
BEGIN
    dummy = 2;
    suspend;
END

While committing the "client B" transaction...

It fails, with the following error:

Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements.
Lock conflict on no wait transaction.
Unsuccessful metadata update.
Object PROCEDURE "TMP_FAB" is in use.
  • Using FireDAC Delphi components (DriverName = FB)
  • Using FIBPlus Delphi components
  • Using IBExpert (It uses it's own firebird's dll)

It succeeds, correctly altering the procedure...

  • Using isql
  • Using DBeaver (It uses JDBC)
  • Using FireDAC Delphi components (DriverName = ODBC)

Which is the cause of these two different behaviors? (Maybe some transaction settings?)


Solution

  • Yes, this is a matter of transactions settings. To be precise the "no wait" option mentioned in the error message. This option is not in the default set so named client applications/components must be setting it explicitly.

    Normally a "wait" transaction when encounters a locked metadata object sends a signal to other transactions/connections/server instances to check if they are still alive and politely ask to release the lock. Then it naturally waits for the lock to be released. "No wait" transactions don't do that returning the error immediately.