Ошибка блокировки базы данных Delphi Xe5 firedac с базой данных SQLite

Я пытаюсь создать простой объект для обработки всех функций, связанных с моей базой данных. У меня есть функции для возврата набора данных или выполнения команды. Теперь, когда я вызываю это из своей программы, я могу извлекать записи с помощью Execute_Dataset, и он работает нормально, но когда я делаю изменения и выполняю команду, вызывая Execute_Command, я получаю сообщение об ошибке «база данных заблокирована» при вызове транзакции фиксации. Я пробовал все, что я мог бы быть, это все еще происходит. Может ли кто-нибудь пролить свет на то, что я делаю неправильно, и как я могу предотвратить это.

  function TConnectionManager.Execute_Dataset(const ASql: string; const AParams:
      array of variant; out VDataset: TDataset; const ATrn_Name: string): Boolean;
  var
    lTrn: TFDTransaction;
    lQry: TFDQuery;
  begin
    Result := True;
    lTrn:= TFDTransaction.Create (Self);
    try
      lTrn.Connection := FConnection;
      lTrn.StartTransaction;
      lQry := TFDQuery.Create (Self);
      lQry.Connection := FConnection;
      lQry.Transaction := lTrn;
      try
        if Length (AParams) > 0
        then lQry.Open (ASql, AParams)
        else lQry.Open (ASql);
        VDataset := lQry;
        Result := True;
        { Commit transaction if started within the procedure }
        lTrn.Commit;
      except
        on e:Exception
        do begin
           { Rollback transaction if started within the procedure }
           lTrn.Rollback;
           lQry.DisposeOf;
           //log
           raise;
        end;
      end;
    finally
      lTrn.DisposeOf;
    end;
  end;



 procedure TConnectionManager.Execute_Command(const ASql: string; const AParams:
      array of variant; const ATrn_Name: string);
  var
    lTrn: TFDTransaction;
    lQry: TFDQuery;
  begin
    lTrn:= TFDTransaction.Create (Self);
    try
      lTrn.Connection := FConnection;
      lTrn.StartTransaction;
      lQry := TFDQuery.Create (Self);
      lQry.Connection := FConnection;
      lQry.Transaction := lTrn;
      try
        { Execute command }
        if Length (AParams) > 0
        then lQry.ExecSQL (ASql, AParams)
        else lQry.ExecSQL (ASql);
        { Commit transaction if started within the procedure }
        lTrn.Commit;
      except
        on e:Exception
        do begin
           { Rollback transaction if started within the procedure }
           lTrn.Rollback;
           //log
           raise;
        end;
      end;
    finally
      lQry.DisposeOf;
      lTrn.DisposeOf;
    end;
  end;

Спасибо


person Razal K.A    schedule 09.04.2014    source источник
comment
Компонент подключения - это то, что я создаю внутри объекта, но вместо этого, если я добавляю компонент подключения в свою форму и передаю его в объект, он работает нормально. Это говорит о том, что есть какое-то свойство, которое не установлено, что вызывает проблему. Существуют ли какие-либо другие свойства, которые должны быть установлены для компонента подключения.   -  person Razal K.A    schedule 10.04.2014
comment
Поставьте подключение на форму, настройте его так, чтобы оно работало должным образом. Затем щелкните правой кнопкой мыши форму, выберите View as text в контекстном меню и найдите соединение. Вы можете увидеть значения свойств компонента из полученного текста. Скопируйте их в буфер обмена. Затем щелкните текст правой кнопкой мыши, выберите View as form и вставьте содержимое буфера обмена в комментарий в своем коде. Затем вы можете установить те же самые свойства в своем коде (и знать, какие значения вы должны присвоить этим свойствам).   -  person Ken White    schedule 10.04.2014
comment
Я пробовал это, и созданное соединение имеет все те же наборы значений, которые представляют собой не что иное, как имя драйвера и путь к файлу базы данных.   -  person Razal K.A    schedule 10.04.2014
comment
Извини. Тогда слишком много недостающей информации. Какова цель параметра ATrn_Name, который вы никогда не используете? Каково содержимое ASql при возникновении исключения? Какой была последняя операция перед исключением (что было сделано последним перед тем, как Exec_Command вызвало исключение)? Если та же самая настройка работает с компонентом в форме, что сообщает вам отладчик, когда вы выполняете код? Здесь много недостающих деталей.   -  person Ken White    schedule 10.04.2014
comment
Привет, я хотел создать и поддерживать другую транзакцию, и ATrn_Name сообщит, какую транзакцию использовать, но я отказался от этой опции и создаю транзакцию для каждой операции, как в коде. Что касается потока, я подключаюсь к базе данных, вызываю execute_reader с оператором select, чтобы получить данные из таблицы, которые будут заполнены в списке, отображаемом на экране. Теперь, когда я пытаюсь добавить новую запись, я вызываю команду execute_command с оператором вставки. Ошибка возникает в момент фиксации транзакции (lTrn.commit) в методе execute_command.   -  person Razal K.A    schedule 10.04.2014
comment
Execute_Dataset кажется мне подозрительным: вы возвращаете активный (открытый) набор данных, но его базовая транзакция уничтожается при выходе. Я бы сказал, что общий подход заключается в том, чтобы сделать транзакцию активной на все время открытия набора данных.   -  person pf1957    schedule 10.04.2014


Ответы (3)


Попробуйте установить для свойств Connection SharedCache значение «False» и LockingMode для «Normal».

Значение по умолчанию для режима блокировки соединения — «эксклюзивный», что может вызвать эту проблему. Вы можете сделать это, щелкнув правой кнопкой мыши свой Connection-Component (в форме) и выбрав ConnectionEditor (я не совсем уверен, правильно ли это английское слово для него, но он должен называться как-то так), а затем установите эти ценности.

В качестве альтернативы вы можете установить эти свойства в исходном коде:

connection.Params.Add('SharedCache=False');
connection.Params.Add('LockingMode=Normal');

Я не уверен, что это лучший способ решить эту проблему. Там может быть лучшее решение для этого.

person Sabine    schedule 16.03.2015

Потому что другие связи существуют. Проверить компонент соединения в модуле данных MyFDConnection.Connected:=False;

person Cfon    schedule 07.03.2019

Sharedcache = false действительно лучший способ решить эту проблему. Компоненты уже поддерживают подключения во время разработки.

person TeoS    schedule 16.08.2019