Delphi 德尔福+;ACCDB:无法更新;当前锁定

Delphi 德尔福+;ACCDB:无法更新;当前锁定,delphi,ms-access-2010,ipc,Delphi,Ms Access 2010,Ipc,我有一个Delphi应用程序,它对数据集中的每条记录执行冗长的计算,并将该记录的结果写入Access 2010 ACCDB中的一个表(其中一个)。由于它可能需要几个小时才能运行,为了加快速度,它会产生一个额外的进程(或多个进程)来处理一半的记录,而主进程处理另一半的记录。所有进程和ACCDB都在一台机器上本地,我使用的是ADO组件(TADOConnection/Table/Query)。为了序列化对数据库的访问,我使用了互斥锁。流程如下所示: procedure AddRecord(aSourc

我有一个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;
procedure AddRecord(aSourceData:TDataSet;aResults:TResults);
开始
互斥体:=CreateMutex(nil,False,'name');
WaitForSingleObject(互斥,无限);

t、 岗位 首先,确保你有足够的时间来阅读托马斯蒂克。如果不设置它,那么就可以了,因为它是所有TcustomadDataSet对象的默认值

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

第三,你可能需要重新思考整个操作。也许最好构造一个或多个,然后以较少的频率和串行方式对物理数据库执行批插入和更新

例如,您可以创建:

  • 每个表一个数据集,或
  • 一个数据集用于插入,另一个用于更新,或
  • 其他一些方案
  • 因此,当内存中的数据集达到任意定义的阈值时,可以通过一次批量操作将数据推送到数据库


    如果无法访问更多的代码、连接设置和其他环境因素,我就不能说得更具体。

    您是否在每个处理读/写的进程中使用事务?不,我没有。我应该吗?特别是在多个进程在同一个数据集上工作的情况下,使用事务总是一件好事。这保证了更新/失败,甚至可能解决您的问题。不幸的是,它引入了另一个错误,在我知道它是否有用之前,我必须跟踪它。请添加连接代码和打开记录集的代码,好吗?我认为这是一个关于游标锁类型的问题:已经尝试了两种方法-没有改变任何东西。事务:现在就尝试这个。内存数据:恐怕这是不可能的。应用程序正在将源数据分组到相似的字段和范围。表和记录是在遇到数据时动态创建的。我不能让两个进程为同一个分组创建单独的表/记录。因此,互斥锁允许一次独占访问一个进程。如果我不能解决这个问题,我将不得不让每个进程创建自己的数据库,然后在以后合并数据。可行,但需要更多的编码。谢谢