I don't know if this is because I just updated my Lazarus yesterday from v4.6 to v4.8. Anyway, mostly finished with this application and was testing a few days ago and most everything working as far as adding, deleting, updating records in all the forms. But today, I can't edit or add any records because I get "Database is Locked". I hate this error, it doesn't make sense.
Here's the way I save in every form. I have an Utils unit that I have added several repeat procedures and just pass the query to the Utils unit.
From my Utils unit, here's the way I coded to SaveQueryChanges, SafeClose and EnsureQueryReady:
procedure SaveQueryChanges(Q: TSQLQuery; Trans: TSQLTransaction);
begin
if Q = nil then Exit;
if Q.State in [dsEdit, dsInsert] then
Q.Post;
if Q.ChangeCount > 0 then
Q.ApplyUpdates;
if Q.Active then
Q.Close;
if Assigned(Trans) and Trans.Active then
begin
Trans.Commit;
Trans.StartTransaction;
end;
end;
procedure SafeClose(const DS: TDataSet);
begin
//=> Close if it's assigned and currently open
if not Assigned(DS) then Exit;
if not DS.Active then Exit;
//=> Don’t close while actively editing...
if DS.State in [dsEdit, dsInsert] then Exit;
{ Cancel cached updates before closing, (optional but useful) }
if DS is TSQLQuery then
TSQLQuery(DS).CancelUpdates;
DS.Close;
end;
procedure EnsureQueryReady(Q: TSQLQuery; ForceRefresh: Boolean);
begin
if not Assigned(Q) then Exit;
//=> Q.Refresh; Never refresh while editing/inserting
if Q.State in [dsEdit, dsInsert] then
Exit;
//=> If refresh, make sure no cached updates are pending
if (Q.ChangeCount > 0) then
Exit;
if Q.Active then
begin
if ForceRefresh then
begin
Q.Close;
Q.Open;
end;
end
else
Q.Open;
end;
So, for example in my Appointments unit testing just editing or adding a new record, which I added 15 records last week and no issues. Here's the coded for a BitBtnSave:
procedure TFrmApptsMgt.BitBtnSaveClick(Sender: TObject);
begin
if QryAppts.FieldByName('CNTKLNAME').AsString = '' then
begin
ShowMessage('WARNING! No Appointment-Contact selected!');
Exit;
end;
try
if (QryAppts.State in [dsEdit, dsInsert]) or (QryAppts.ChangeCount > 0) then
begin
SafeClose(QryCntks);
SafeClose(QryClients);
SafeClose(DSrcStates.DataSet);
SafeClose(DSrcCntries.DataSet);
SaveQueryChanges(QryAppts, PMSDataModule.TransPMSDB);
EnsureQueryReady(QryAppts, True);
EnsureQueryReady(QryCntks, False);
EnsureQueryReady(QryClients, False);
ReOpenQuery(PMSDataModule.QryStates);
ReOpenQuery(PMSDataModule.QryCntries);
UpDateTTLAppts;
end;
except on E: Exception do
begin
PMSDataModule.TransPMSDB.Rollback;
ShowMessage('Error saving current Appointment record: '+E.Message);
end;
end;
end;
Some of this code may not be necessary but just trying to cover all bases because of this 'Database is Locked' error!
Any ideas, I would like to try anyone's advice, Thanks!