I am trying to create a simple object to handle all my database related functions. I have a functions to return a dataset or to execute a command. Now when i call this from my program I am able to fetch records using Execute_Dataset and it works fine but when i do an changes and execute a command by calling Execute_Command i get an error "database is locked" when the commit transaction is called. I have tried everything that i could be it still happens. Can someone put some light into what i am doing wrong and how i can prevent this from happening.
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;
Thanks
Try setting the Connection's properties SharedCache
to 'False' and LockingMode
to 'Normal'.
The default value for the connection's locking mode is 'exclusive' which can cause this problem. You can do this by right clicking on your Connection-Component (on the form) and choosing ConnectionEditor
(I'm not quite sure, if that's the right English word for it, but it should be called something like that) and then setting these values.
Alternatively you can set these properties in sourcecode:
connection.Params.Add('SharedCache=False');
connection.Params.Add('LockingMode=Normal');
I'm not sure that this is the best way to solve this problem. There might be a better solution to this.
Because other connection exist. Check connection component in datamodule MyFDConnection.Connected:=False;
Sharedcache = false is indeed the best way to solve this problem. The components already support designtime connections.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.