Delphi + ACCDB:无法更新;目前锁定

时间:2014-03-25 01:42:18

标签: delphi ms-access-2010 ipc

我有一个Delphi应用程序,它对数据集中的每个记录执行冗长的计算,并将该记录的结果写入Access 2010 ACCDB中的表(其中一个)。因为它可能需要几个小时才能运行,为了加快速度,它会产生一个额外的进程(或多个进程)来处理一半的记录,而主进程处理另一半。所有进程和ACCDB都是一台机器的本地,我正在使用ADO组件(TADOConnection / Table / Query)。要序列化对数据库的访问,我使用的是互斥锁。流程如下:

procedure AddRecord(aSourceData: TDataSet; aResults: TResults);
begin
  mutex := CreateMutex(nil, False, ‘name’);
  WaitForSingleObject(mutex, INFINITE);
  <find the table, t, to write to>
  <search for the record in table>
  <if found, t.Edit; else t.Append>
  <update fields in table from aSourceData and aResults>
  t.Post;  <== Error
  ReleaseMutex(mutex);
end;

我认为互斥锁可以避免任何锁定问题,因为一次只允许一个进程攻击数据库,但是我得到零星的“无法更新;目前锁定“错误。有时它完成没有错误,并且错误可以在两个过程中的任何一个中发生。我尝试过包含OnPostError处理程序并允许最多10次重试。有时它会让它继续,有时它仍会失败。

我有没有想过的时间问题?例如,一个进程完成其Post和ReleaseMutex调用,但另一个进程获取互斥锁并尝试在清除ACCDB锁之前更新同一个表/记录。

欢迎任何想法。 TIA。

1 个答案:

答案 0 :(得分:0)

首先,确保您拥有locking type on the table or recordset到ltOptomistic。如果你没有设置它,那么你很好,因为它是所有TCustomADODataset对象的默认值。

其次,您可能希望重构代码并使用事务。通常,这是通过您的TADOConnection使用BeginTransCommitTrans函数完成的。

第三,您可能想重新考虑整个操作。也许最好构造一个或多个in-memory datasets,然后以较低的频率和串行方式对物理数据库执行批量插入和更新。

例如,您可以创建:

  1. 每个表一个数据集,或
  2. 一个数据集用于插入,另一个用于更新,或
  3. 其他一些计划。
  4. 因此,当您达到内存数据集的任意定义阈值时,您可以将数据推送到数据库中。

    无法访问更多代码,连接设置和其他环境因素,我无法更具体。