如何使Firebird客户端应用程序等待行解锁

nol*_*ker 16 delphi firebird interbase dbexpress

我熟悉使用ADO(dbGo)的Microsoft SQL服务器世界,我已经为该环境编写了许多应用程序.现在我有一个遗留的Delphi 7应用程序和Firebird 2.5数据库,我必须维护它.

但我发现如果2个客户端应用程序执行此操作:

SQLQuery.SQL.Text := 'Update mytable set field1 = 11 where keyfield = 99'
SQLQuery.Execute;
Run Code Online (Sandbox Code Playgroud)

在几乎完全相同的时间,第二个应用程序立即出现"死锁"错误.在SQL Server中,会有一段等待时间

ADOConnection.Isolationlevel = ilCursorstability;
ADOConnection.CommandTimeout := 5;
Run Code Online (Sandbox Code Playgroud)

在第二个客户端应用程序中引发任何异常之前.异常处理可能涉及在批处理过程中被视为非常不寻常的情况的回滚.这是合理的.5秒是计算机处理时间非常长的时间.

现在,我在Firebird客户端上使用相同方法的尝试毫无结果,因为"死锁"(实际上是使用中的记录)立即发生.

如果无法将数据库引擎配置为等待一些条件来改进(记录锁定要发布),那么现在责任必须由客户端应用程序开发人员负责,他们必须编写疯狂的慢速代码来克服我认为是主要的Firebird失败了.

一旦检测到"死锁",除非断开连接组件,否则不会清除该情况

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

当您在使用Delphi中的DBX时在Firebird中没有任何实质性的锁定容差时,如何构建健壮的多用户表更新客户端?

Ond*_*lle 7

客户端可以指定事务是否应该等待死锁解析.如果在您的情况下立即发生死锁,可能是因为您的配置(nowait在客户端上使用事务参数).不使用nowait将导致服务器端检测到死锁并且(在可配置的超时之后)在客户端上引发异常.

Firebird 2.0开始,您还可以从客户端指定事务的锁定超时,从而覆盖服务器配置的超时值.