You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FireDAC+Interbase部分窗体仅关闭应用后才更新数据库的问题

Delphi 10.3 + FireDAC + Interbase 更新延迟问题处理

问题场景

使用Delphi 10.3结合FireDAC连接Interbase数据库时,多数窗体执行Update语句后调用Commit能立即生效,但在某一窗体中,两次Update之间存在查询Open操作时,第二次Update不会立即更新数据库,必须关闭窗体并退出应用后才生效。

已发现的触发规律

单独执行Update后调用Commit可正常生效;但当两次Update中间插入查询Open操作时,必须在Open前调用StartTransaction,Open完成后执行Commit,后续的第二次Update才能立即生效。相关代码示例:

DM_IB.IBF_VHE.ExecSQL('Update BB_ASML_FORECAST set Uren_Montage = 100, Uren_Berekend = ''Ja'' ' +
                      'where AANMAAK_DATUMTIJD = ''19-10-2022 10:12:38'' and ItemCode = ''4022.472.18632'' ') ;

DM_IB.IBF_VHE.Commit ;

ShowMessage('1') ; // 无问题,正常生效

MEM_VPA.DisableControls ;
MEM_Fouten.DisableControls ;

Post_Confirm := False ;

Try
  MEM_VPA.Close ;
  MEM_VPA.Open ;
  MEM_VPA.EmptyTable ;

  MEM_Fouten.Close ;
  MEM_Fouten.Open ;
  MEM_Fouten.EmptyTable ;

  With TFDQuery.Create(nil) do
  Try
    Connection := DM_IB.IBF_VHE ;
    SQL.Text   := 'select * from PL_CAPACITEIT_NPW where ' +
                  '(jaar = ' + FormatDateTime('yyyy', now()) + ' and ' +
                  'Weeknummer > ' + IntToStr(WeekofTheyear(Now())) + ') or ' +
                  '(jaar = ' + FormatDateTime('yyyy', IncYear(Now())) + ' and ' +
                  'weeknummer < ' + IntToStr(52 - (52 - WeekofTheyear(Now()))) + ') order by jaar, weeknummer' ;
    DM_IB.IBF_VHE.StartTransaction ; // 若不加此行及后续Commit,下方更新需等到应用结束才生效
    Open ;
    DM_IB.IBF_VHE.Commit ;

    DM_IB.IBF_VHE.StartTransaction ;

    DM_IB.IBF_VHE.ExecSQL('Update BB_ASML_FORECAST set Uren_Montage = 100, Uren_Berekend = ''Ja'' ' +
                          'where AANMAAK_DATUMTIJD = ''19-10-2022 10:12:38'' and ItemCode = ''4022.472.88135'' ') ;

    DM_IB.IBF_VHE.Commit ;

    ShowMessage('2') ; // 仅当上述Open操作处于事务中时才生效

原因分析

FireDAC默认事务行为中,当执行查询(Open)操作时,如果没有显式开启事务,FireDAC会隐式启动一个事务,并且不会自动提交这个事务。后续的Update操作会被纳入这个未提交的隐式事务中,只有当连接被关闭(比如应用退出)时,事务才会被提交,导致更新延迟生效。

解决方案

  1. 显式管理所有事务:无论是查询还是更新操作,都显式调用StartTransaction和Commit,确保每个操作的事务及时结束,避免隐式事务堆积。
  2. 调整AutoCommit属性:将FireDAC连接组件的TxOptions.AutoCommit设置为True,这样每个数据库操作都会自动提交事务,无需手动调用Commit。但注意此模式下无法实现跨多个操作的原子性事务,适合单步独立操作场景。
  3. 统一处理EmptyTable操作:EmptyTable本质也是数据修改操作,建议同样包裹在显式事务中执行,避免触发额外的隐式事务。

内容的提问来源于stack exchange,提问作者FvS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:11:16