我熟悉的是使用ADO(dbGo)的Microsoft sql Server世界,我已经为该环境编写了许多应用程序.现在我有一个传统的Delphi 7应用程序与一个Firebird 2.5数据库,我必须维护.
但是我发现如果2个客户端应用程序执行这个:
sqlQuery.sql.Text := 'Update mytable set field1 = 11 where keyfield = 99' sqlQuery.Execute;
在几乎完全相同的时间,第二个应用程序立即获得“死锁”错误.在sql Server中,会有一个等待期
ADOConnection.Isolationlevel = ilCursorstability; ADOConnection.CommandTimeout := 5;
在第二个客户端应用程序中引发任何异常之前.异常处理可能涉及在批处理过程中被视为非常不寻常的情况的回滚.这是合理的. 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;
当您在Firebird中没有任何实质的锁容忍时,如何在Delphi中使用DBX,如何使强大的多用户表更新客户端?
解决方法
客户端可以指定事务是否应该等待死锁解决.如果在这种情况下,死锁立即发生,可能是因为您的配置(在客户端使用nowait事务参数).不使用nowait将导致服务器端检测到死锁,并且(在可配置的超时后)会在客户端引发异常.
自Firebird 2.0以来,您还可以从客户端指定事务的锁定超时,覆盖服务器配置的超时值.