我正在尝试创建一个简单的对象来处理我所有与数据库相关的函数。我有一个返回数据集或执行命令的函数。现在当我从我的程序中调用它时,我能够使用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;
由于
答案 0 :(得分:3)
尝试将Connection的属性SharedCache
设置为'False',将LockingMode
设置为'Normal'。
连接锁定模式的默认值是'exclusive',这可能会导致此问题。您可以通过右键单击Connection-Component(在表单上)并选择ConnectionEditor
来执行此操作(我不太确定,如果这是正确的英语单词,但它应该被称为类似的东西)然后设置这些值。
或者,您可以在源代码中设置这些属性:
connection.Params.Add('SharedCache=False');
connection.Params.Add('LockingMode=Normal');
我不确定这是解决此问题的最佳方法。可能有更好的解决方案。
答案 1 :(得分:0)
因为存在其他连接。检查数据模块中的连接组件 MyFDConnection.Connected:= False;
答案 2 :(得分:0)
Sharedcache = false确实是解决此问题的最佳方法。这些组件已经支持设计时连接。