Recent

Author Topic: TIBDataSet "Closing"? on .ApplyUpdates  (Read 873 times)

RedOctober

  • Sr. Member
  • ****
  • Posts: 475
TIBDataSet "Closing"? on .ApplyUpdates
« on: December 11, 2025, 05:00:04 pm »
When I updated my Lazarus from 3x to 4.4 all my database projects started throwing various different errors when accessing their Firebird 3.13 databases.  Note:  ALL my projects worked without error under 3x.  None of them work under 4.4  All the same source code, same database.

Platform:
Lazarus 4.4 (rev lazarus_4_4) FPC 3.2.2 x86_64-win64-win32/win64

Server Version: WI-V3.0.13.33818 Firebird 3.0
Server Implementation: Firebird/Windows/AMD/Intel/x64
Service Version: 2

See attached .json file to see the relevant installed packages.

This same code works flawlessly under Lazarus 3.x with the older IB/IBX components. Errors where shown under Lazarus 4.4:

Code: Pascal  [Select][+][-]
  1.  
  2.  
  3.       if trRsp.InTransaction then
  4.         begin
  5.           if dstRsp.State in dsEditModes then
  6.             begin
  7.               pst_rid := dstRsp.ParamByName('PST_RID').AsInt64;
  8.               dstRsp.ApplyUpdates;
  9.               trRsp.Commit;  // <---- Error occurs here: "Operation cannot be performed on an inactive dataset."
  10.             end
  11.           else
  12.             trRsp.Commit;
  13.         end;
  14.  
  15.  

It seems that .ApplyUpdates is causing the TIBTransaction to "Commit" in the latest version of components but it did not in the earlier version.

Any help would be greatly appreciated.

UPDATE:  Further Info:  It seems that the problem is with one of the controls attached to the TIBDataSet. When I do a DisableControls, the error display problem goes away.  I suspect the problem is in the TDBCheckBoxes connected to the TIBDataSet.  That is the only control type connected to this TIBDataset.  Doing a .DisableControls DISCARDS the value in the checkbox, so this is not a solution, it's just a debug technique.  I must NOT do a .DisableControls in the production code.

Here is code that doesn't error:

Code: Pascal  [Select][+][-]
  1.  
  2.       if trRsp.InTransaction then
  3.         begin
  4.           if dstRsp.State in dsEditModes then
  5.             begin
  6.               pst_rid := dstRsp.ParamByName('PST_RID').AsInt64;
  7.               dstRsp.DisableControls;  // DEBUG: Added (Also tosses away the TDBCheckBox setting)
  8.               dstRsp.ApplyUpdates;  
  9.               trRsp.Commit;  // Works ok now, carries on with subsequent code
  10.             end
  11.           else
  12.             begin
  13.               trRsp.Commit;
  14.             end;
  15.         end;
  16.  
  17.  




« Last Edit: December 11, 2025, 08:48:20 pm by RedOctober »

Zvoni

  • Hero Member
  • *****
  • Posts: 3230
Re: TIBDataSet "Closing"? on .ApplyUpdates
« Reply #1 on: December 12, 2025, 02:41:36 pm »
1) Isn't there a "Post"-Operation missing before ApplyUpdates?
2) Is it possible that there is an option "AutoCommit" or something set?
3) I seem to remember, that you need CommitRetaining instead of Commit to keep the Dataset/Transaction "alive"
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

RedOctober

  • Sr. Member
  • ****
  • Posts: 475
Re: TIBDataSet "Closing"? on .ApplyUpdates
« Reply #2 on: December 12, 2025, 03:09:07 pm »
Hi Zvoni.  I tried incorporating a .Post and the issue remains.

The following does not fix the problem:

Code: Pascal  [Select][+][-]
  1.       // Try 1
  2.       dstRsp.Post;
  3.       dstRsp.ApplyUpdates;
  4.       trRsp.Commit;
  5.  
  6.       // Try 2
  7.       dstRsp.Post;
  8.       //dstRsp.ApplyUpdates;
  9.       trRsp.Commit;
  10.  

I am going to build a "demonstration" project that will either demonstrate the problem, or point me in a new direction for investigation.

From Brave Browser's AI:

Quote

However, if you are managing transactions manually (e.g., by starting a transaction before calling ApplyUpdates), then you are responsible for calling Commit or Rollback on the TIBTransaction component after ApplyUpdates returns, based on its result. In this case, ApplyUpdates will use your existing transaction and will not commit it for you.

In summary, ApplyUpdates applies changes within a transaction; the final Commit is either handled automatically by the TDataSetProvider in a multi-tier setup or must be performed manually by your code if you control the transaction.


Also:

Quote
The TCustomClientDataSet.ApplyUpdates method automatically calls CheckBrowseMode, which in turn calls Post if the dataset is in dsEdit or dsInsert state and has modified records.

Remember, this exact code worked flawlessly when compiled in my Lazarus 3x.


« Last Edit: December 12, 2025, 05:04:36 pm by RedOctober »

egsuh

  • Hero Member
  • *****
  • Posts: 1734
Re: TIBDataSet "Closing"? on .ApplyUpdates
« Reply #3 on: December 13, 2025, 09:14:47 am »
What is pst_rid? Limiting your posted codes, there are no change in the dataset (dstRsp), and nothing to update.

RedOctober

  • Sr. Member
  • ****
  • Posts: 475
Re: TIBDataSet "Closing"? on .ApplyUpdates
« Reply #4 on: December 13, 2025, 02:38:05 pm »
I decided for now, I would just "patch" every single occurrence of Commit and RollBack as follows:

Code: Pascal  [Select][+][-]
  1.  
  2.       if trRsp.InTransaction then
  3.         begin
  4.           if dstRsp.State in dsEditModes then
  5.             begin
  6.               pst_rid := dstRsp.ParamByName('PST_RID').AsInt64;
  7.               dstRsp.ApplyUpdates;
  8.               dstRsp.DisableControls;
  9.               trRsp.Commit;
  10.             end
  11.           else
  12.             begin
  13.               dstRsp.DisableControls;
  14.               trRsp.Commit;
  15.             end;
  16.         end;
  17.       trRsp.StartTransaction;
  18.       dstRsp.ParamByName('PST_RID').AsInt64 := pst_rid;
  19.       dstRsp.ParamByName('USR_RID').AsInt64 := GV.UsrProps.usr_rid;
  20.       dstRsp.Open;
  21.       dstRsp.FetchAll;
  22.       dstRsp.EnableControls;
  23.  
  24.  
  25.  


This allows my Lazarus 4.4 code to continue to run, but is sub-optimal because it doesn't get to the root of the problem.

To answer the pst_rid question:   It's a value I need later in the procedure, not related to the problem at hand.  The TIBDataSet has TDBCheckBox (es) connected to it, that may or may not have had their values changed by the user.  When I Commit, it closes the transaction, so I want to reopen the TIBDataSet at the same record immediately after posting, so I need that pst_rid to look it up again.


1HuntnMan

  • Sr. Member
  • ****
  • Posts: 421
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: TIBDataSet "Closing"? on .ApplyUpdates
« Reply #5 on: December 14, 2025, 03:05:34 pm »
Hi, I was having some of these issues. Does your query property - options have any of those settings active, i.e. AutoApplyUpdates, AutoCommit set. I found awhile back to make sure all of the Query options aren't set from the beginning, then on saving: POST, APPYUPDATES, TRANSACTION.COMMIT, Qry.Close, Qry.Open. Also, Disabling and Enabling controls, I only use those commands when batch updating or retrieving values from one table into another, i.e. in my Appointments unit/form looking up the contact for the appointment, I QryAppts.DisableControls then try... pulling the field values from contacts, i.e. Email, Cell Phone, Address, etc. and then finally QryAppts.EnableControls.

Here awhile back, I'm in a learning phase all the time in Lazarus. So, learn from folks here on the forum. But, was getting access type errors that didn't make sense esp. if I had autocommit active in the options. I just disable any options from the get go, then do my own thing.  But, something that I don't understand, anytime testing/running within Lazarus, I get access errors on exiting the application I'm testing.  But, it I run the executible outside of Laz, I don't get this error???

I'll stay in tune to see what you discover...

cdbc

  • Hero Member
  • *****
  • Posts: 2565
    • http://www.cdbc.dk
Re: TIBDataSet "Closing"? on .ApplyUpdates
« Reply #6 on: December 14, 2025, 03:26:35 pm »
Hi
Quote
But, it I run the executible outside of Laz, I don't get this error???
Have you got your datasets open in Lazarus?!? That could be it...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

RedOctober

  • Sr. Member
  • ****
  • Posts: 475
Re: TIBDataSet "Closing"? on .ApplyUpdates
« Reply #7 on: December 14, 2025, 04:52:18 pm »
Hi 1HuntnMan,

Thanks for your input.  Remember that this code ran flawlessly when compiled with Lazarus 3.x.  That includes what ever settings I had then, worked.  The exact same code compiled under Lazarus 4.x manifests the error.  I did not change any "auto" type settings.  My "patch" code is now working, similar to what you said you do.

The error on close that you are getting could be caused by you .Free ing an object that is automatically freed by it's parent object.  Here are my suggestions:

- Check for Assignment before freeing.

if Assigned(my_string_list) then
  my_string_list.Free;

- Always put these destructive functions in the .OnDestroy method, not the .OnClose method of your main form:

procedure MyProject.OnDestroy;
begin
  if Assigned(my_string_list) then
    my_string_list.Free;
end;

Also, never free an object that has a parent.  Even if you created it.

Example:

...
var MyEdit: TEdit;
begin
   MyEdit := TEdit.Create(Form1);
   MyEdit.Top := 10;
   MyEdit.Left := 10;
end
...
procedure Form1.OnClose;
begin
  MyEdit.Free;  // <-- This is not necessary.  Form1 will destroy MyEdit for you.
end;

Such an error will show up when running in Lazarus because of the debugger/Run mode you selected.  Just running the .exe on it's own will allow the underlying code to crash silently, even though the same errant process is happening.

Anyway, a bit off topic.  Thanks for all the help everyone.  I will consider this question closed, since I now have my code working.




1HuntnMan

  • Sr. Member
  • ****
  • Posts: 421
  • From Delphi 7 to Lazarus
    • NewFound Photo Art
Re: TIBDataSet "Closing"? on .ApplyUpdates
« Reply #8 on: December 21, 2025, 03:13:07 pm »
Red October, you are 100% correct.  Fixed alot of issues using OnDestroy and not shutting down in OnClose as you recommended and also free objects that are already freed.  I'm glad I read your post and you reply. Thanks...

 

TinyPortal © 2005-2018