1

データベース関連のすべての機能を処理する単純なオブジェクトを作成しようとしています。データセットを返すか、コマンドを実行する関数があります。プログラムからこれを呼び出すと、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;

ありがとう

4

3 に答える 3

3

接続のプロパティSharedCacheを「False」とLockingMode「Normal」に設定してみてください。

接続のロック モードのデフォルト値は「排他的」であり、この問題が発生する可能性があります。これを行うには、Connection-Component (フォーム上) を右クリックしてConnectionEditor(それが適切な英単語かどうかはよくわかりませんが、そのような名前にする必要があります) を選択し、これらの値を設定します。 .

または、ソースコードでこれらのプロパティを設定できます。

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

これがこの問題を解決する最善の方法かどうかはわかりません。これにはもっと良い解決策があるかもしれません。

于 2015-03-16T08:53:26.187 に答える