如何使用 FireDAC 为 Firebird (InterBase) 设置事务锁定超时?

How to set transaction LOCK TIMEOUT for Firebird (InterBase) using FireDAC?

使用

时,TFDConnection 似乎没有设置锁定超时
TFDConnection.UpdateOptions.LockMode := lmPessimistic;
TFDConnection.UpdateOptions.LockWait := true;

A TFDTransaction 似乎也没有它的属性。

The Firebird SET TRANSACTION documentation建议可以设置LOCK TIMEOUT。

我在设置超时 属性 时是否忽略了什么,或者我必须在打开连接后求助于执行 SET TRANSACTION LOCK TIMEOUT
如果我在 FireDAC.Phys.IB*.pas 文件中查找,我会看到对 isc_tpb_lock_timeout 的引用,但无法使用它们?

这可以通过 IBAdvanced 参数定义(参见 Connect to Interbase (FireDAC)):

The ';' separated list of additional parameters. You can find the full list of the supported parameters in the FireDAC.Phys.IBWrapper unit (see the DPBInfos constant array). You can find the description of each Code listed there in the Interbase manuals.

这是 FireDAC.Phys.IBWrapper 中定义它们的部分*:

const
  TRPBInfo_Items = 24;
  TRPBInfos: array[1 .. TRPBInfo_Items] of TIBPBInfo = (
    (Name: 'consistency';      ParamType: prNoneNoZ; Code: isc_tpb_consistency),
    (Name: 'concurrency';      ParamType: prNoneNoZ; Code: isc_tpb_concurrency),
    (Name: 'shared';           ParamType: prNoneNoZ; Code: isc_tpb_shared),
    (Name: 'protected';        ParamType: prNoneNoZ; Code: isc_tpb_protected),
    (Name: 'exclusive';        ParamType: prNoneNoZ; Code: isc_tpb_exclusive),
    (Name: 'wait';             ParamType: prNoneNoZ; Code: isc_tpb_wait),
    (Name: 'nowait';           ParamType: prNoneNoZ; Code: isc_tpb_nowait),
    (Name: 'read';             ParamType: prNoneNoZ; Code: isc_tpb_read),
    (Name: 'write';            ParamType: prNoneNoZ; Code: isc_tpb_write),
    (Name: 'lock_read';        ParamType: prStrg;    Code: isc_tpb_lock_read),
    (Name: 'lock_write';       ParamType: prStrg;    Code: isc_tpb_lock_write),
    (Name: 'verb_time';        ParamType: prNoneNoZ; Code: isc_tpb_verb_time),
    (Name: 'commit_time';      ParamType: prNoneNoZ; Code: isc_tpb_commit_time),
    (Name: 'ignore_limbo';     ParamType: prNoneNoZ; Code: isc_tpb_ignore_limbo),
    (Name: 'read_committed';   ParamType: prNoneNoZ; Code: isc_tpb_read_committed),
    (Name: 'autocommit';       ParamType: prNoneNoZ; Code: isc_tpb_autocommit),
    (Name: 'rec_version';      ParamType: prNoneNoZ; Code: isc_tpb_rec_version),
    (Name: 'no_rec_version';   ParamType: prNoneNoZ; Code: isc_tpb_no_rec_version),
    (Name: 'restart_requests'; ParamType: prNoneNoZ; Code: isc_tpb_restart_requests),
    (Name: 'no_auto_undo';     ParamType: prNoneNoZ; Code: isc_tpb_no_auto_undo),
    // IB75
    (Name: 'no_savepoint';     ParamType: prNoneNoZ; Code: isc_tpb_no_savepoint),
    // FB20
    (Name: 'lock_timeout';     ParamType: prCard;    Code: isc_tpb_lock_timeout),
    // IB2017
    (Name: 'exclusivity';      ParamType: prNoneNoZ; Code: isc_tpb_exclusive),
    (Name: 'wait_time';        ParamType: prCard;    Code: isc_tpb_wait_time)
   );

所以,例如5 秒超时:

TFDConnection.Params.Add('IBAdvanced=lock_timeout=5');

* 请注意,文档说明它们在 DPBInfos 中,但它们在 TRPBInfos 中。