fireDAC访问的SQLite中的表锁

fireDAC访问的SQLite中的表锁,sqlite,delphi,firedac,delphi-10.2-tokyo,Sqlite,Delphi,Firedac,Delphi 10.2 Tokyo,我正在将一组paradox表移植到SQLite。为此,我创建了一个测试应用程序,模拟(某种程度上)当前的使用场景:多个用户访问同一个DB文件并同时执行读写操作 该应用程序非常简单:它将启动几个线程,每个线程创建一个连接,打开一个表,并将随机读取、更新或插入表中 应用程序几乎立即遇到“数据库表锁定”错误。我尝试过几种方法来解决这个问题,但似乎没有任何效果。我做错了什么 以下是线程内部的代码: procedure testDB(TargetFolder: string); var Conn: T

我正在将一组paradox表移植到SQLite。为此,我创建了一个测试应用程序,模拟(某种程度上)当前的使用场景:多个用户访问同一个DB文件并同时执行读写操作

该应用程序非常简单:它将启动几个线程,每个线程创建一个连接,打开一个表,并将随机读取、更新或插入表中

应用程序几乎立即遇到“数据库表锁定”错误。我尝试过几种方法来解决这个问题,但似乎没有任何效果。我做错了什么

以下是线程内部的代码:

procedure testDB(TargetFolder: string);
var
  Conn: TFDConnection;
  Table: TFDTable;
  i: Integer;
begin
  randomize;
  Conn := TFDConnection.Create(nil);
  try
    Conn.DriverName := 'SQLite';
    Conn.LoginPrompt := false;
    Conn.Params.clear;
    Conn.Params.Database := TPath.Combine(TargetFolder, 'testDB.sdb');
    Conn.Params.Add('DriverID=SQLite');
    // all this is the result of several attemp to fix the table locking error. none worked

    Conn.Params.Add('LockingMode=Normal');
    Conn.Params.Add('Synchronous=Normal');
    Conn.UpdateOptions.UpdateMode := TUpdateMode.upWhereAll;
    Conn.UpdateOptions.LockWait := True;
    Conn.UpdateOptions.LockMode := TFDLockMode.lmPessimistic;
    Conn.UpdateOptions.LockPoint := TFDLockPoint.lpImmediate;
    Conn.UpdateOptions.AssignedValues := [uvLockMode,uvLockPoint,uvLockWait];
    Conn.Open();
    Conn.ExecSQL('CREATE TABLE IF NOT EXISTS ''test'' (''ID''   INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,''data1'' TEXT NOT NULL,''data2'' INTEGER NOT NULL)');
    Table := TFDTable.Create(nil);
    try
      table.Connection := Conn;
      while True do
      begin
        case Trunc(Random(10)) of
          0..3:
          begin
            table.Open('test');
            try
              if table.Locate('data1', 'name'+intToStr(Trunc(Random(10))),[TLocateOption.loCaseInsensitive]) then
              begin
                table.Edit;
                table.FieldByName('data2').AsInteger := table.FieldByName('data2').AsInteger + 1;
                table.Post;
              end;
            finally
              table.close;
            end;
          end;
          4..8:
          begin
            table.Open('test');
            try
              i := Trunc(Random(10));
              if not table.Locate('data1', 'name'+ i.ToString,[TLocateOption.loCaseInsensitive]) then
              begin
                table.AppendRecord([null, 'name'+ i.ToString, 0]);
              end;
            finally
              table.close;
            end;
          end
        else
          break;
        end;
      end;
    finally
      FreeAndNil(Table);
    end;
  finally
    FreeAndNil(Conn);
  end;
end;
多亏了,我找到了正确的参数

  Conn := TFDConnection.Create(nil);
  try
    Conn.DriverName := 'SQLite';
    Conn.LoginPrompt := false;
    Conn.Params.clear;
    Conn.Params.Database := TPath.Combine(TargetFolder, 'testDB.sdb');
    Conn.Params.Add('DriverID=SQLite');
    Conn.Params.Add('SharedCache=False');
    Conn.Params.Add('LockingMode=Normal');
    Conn.Params.Add('Synchronous=Normal');
    Conn.UpdateOptions.LockWait := True;
    Conn.Open();

再次感谢

在中,您将找到所需的所有内容。谢谢,我找到了正确的参数。如果你写一个答案,我就接受。否则,我将自己回答这个问题。请发布一个答案。我现在很忙..根据文档,
UpdateOptions.LockWait
不使用,除非
UpdateOptions.LockMode=lm悲观
(默认为
lmNone
)。