title: SQLTransaction2 : Operation cannot be performed on an active transaction FreePascal - Code Typhon
body: <p>I would like some help solving this error message.</p>
  
  <p>I am using Code Typhon32 V4.9 on Windows 7 Pro.</p>
  
  <p>I had a project connecting to a firebird database, 
  Single form which works fine- No problems.</p>
  
  <p>I added a 2nd form to be my data entry form linked to another Database in 
  Firebird - I need both databases in one project. </p>
  
  <p>Since adding the 2nd form I am getting the following error when I close code typhon and when I close Form1 while using the debugger: "SQLTransaction2 : Operation cannot be performed on an active transaction"</p>
  
  <p>I have tried numerous of solution found on the internet but can not solve it.</p>
  
  <p>I have a button that open the 2nd from as Follows: </p>
  
  <pre><code>procedure TForm1.BitBtn1Click(Sender: TObject);
  begin
  frmContributions := TfrmContributions.Create(nil);
    try
  frmContributions.ShowModal;
   finally
  frmContributions.Free;
  end;
  end; 
  </code></pre>
  
  <p>Here is my 2nd form Code: </p>
  
  <pre><code>unit uFirebirdDemo1;
  
  {$mode objfpc}{$H+}
  
  interface
  
  uses
  Classes, SysUtils, sqldb, IBConnection, pqconnection, db, FileUtil, Forms,
  Controls, Graphics, Dialogs, StdCtrls, DBGrids, DbCtrls;
  
  type
  TfrmContributions = class(TForm)
  btnUpdate: TButton;
  btnDeleteProgrammer: TButton;
  dsProgrammer: TDatasource;
  dbgrdProgrammer: TDBGrid;
  dbnavProgrammer: TDBNavigator;
  IBConnection2: TIBConnection;
  sqlqProgrammer: TSQLQuery;
  SQLScript1: TSQLScript;
  SQLTransaction2: TSQLTransaction;
  procedure btnDeleteProgramClick(Sender: TObject);
  procedure btnUpdateClick(Sender: TObject);
  procedure btnUpdateProgramsClick(Sender: TObject);
  procedure btnDeleteProgrammerClick(Sender: TObject);
  procedure dbgrdCombinedTitleClick(Column: TColumn);
  procedure dbgrdProgrammerTitleClick(Column: TColumn);
  procedure dbgrdProgramsTitleClick(Column: TColumn);
  procedure edtSearchChange(Sender: TObject);
  procedure Savechanges;
  procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    end;
   var
  frmContributions: TfrmContributions;
  
  implementation
  
  {$R *.lfm}
  
  procedure TfrmContributions.btnUpdateClick(Sender: TObject);
  begin
  sqlqProgrammer.Edit;
  sqlqProgrammer.Post;
  sqlqProgrammer.ApplyUpdates(1);
  SQLTransaction2.CommitRetaining;
  end;
  
  
  procedure TfrmContributions.btnDeleteProgrammerClick(Sender: TObject);
  begin
  SQLScript1.Script.Text:= 'Delete from Programmer WHERE ID = ' + dbgrdProgrammer.Columns[0].Field.AsString + ';';
  SQLScript1.Execute;
  SQLTransaction2.CommitRetaining;
  sqlqProgrammer.Refresh;
  end;
  
  procedure TfrmContributions.dbgrdProgrammerTitleClick(Column: TColumn);
  begin
  sqlqProgrammer.Close;
  SQLTransaction2.Active := TRUE;
  sqlqProgrammer.SQL.Text := 'Select * from Programmer ORDER BY ID DESC';
  sqlqProgrammer.Open;
  end;
  
  procedure TfrmContributions.Savechanges;
  // Saves edits done by user, if any.
  begin
  try
  if SQLTransaction2.Active then
  // Only if we are within a started transaction
  // otherwise you get "Operation cannot be performed on an inactive dataset"
  begin
    sqlqProgrammer.ApplyUpdates; //Pass user-generated changes back to database...
    SQLTransaction2.Commit; //... and commit them using the transaction.
    //SQLTransaction2.Active now is false
   end;
   except
   on E: EDatabaseError do
   begin
    MessageDlg('Error', 'A database error has occurred. Technical error message: ' +
      E.Message, mtError, [mbOK], 0);
        end;
   end;
   end;
  procedure TfrmContributions.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  begin
  SaveChanges;
  sqlqProgrammer.Close;
  SQLTransaction2.Commit;
  SQLTransaction2.RollBack;
  SQLTransaction2.Active := False;
  IBConnection2.Connected  := False;
  end;
  
  end.  
  </code></pre>
  
  <p>I tried adding a formclose to my first form as follows in order to solved the problem
  but it does not seem to be doing anything:</p>
  
  <pre><code>procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  begin
  frmContributions.SaveChanges;
  frmContributions.SQLTransaction2.RollBack;
  frmContributions.SQLTransaction2.Active := False;
  frmContributions.IBConnection2.Connected  := False;
  end;
  </code></pre>
  
  <p>I have tried different solutions found on the internet but I am still getting:</p>
  
  <p>"SQLTransaction2 : Operation cannot be performed on an active transaction" when i
  close my project using the debugger, and also I get the same error when closing down
  code typhon.</p>
  
  <p>Here is the lfm file:</p>
  
  <pre><code>object frmContributions: TfrmContributions
  Left = 816
  Height = 415
  Top = 172
  Width = 774
  Caption = 'Data Entry for Promo'
  ClientHeight = 415
  ClientWidth = 774
  Color = clHighlight
  OnClose = FormClose
  LCLVersion = '1.3'
  object btnUpdate: TButton
  Left = 536
  Height = 25
  Top = 376
  Width = 168
  Caption = 'Update programmers'
  OnClick = btnUpdateClick
  TabOrder = 0
  end
  object dbgrdProgrammer: TDBGrid
  Left = 16
  Height = 360
  Top = 0
  Width = 744
  Color = clWindow
  Columns = &lt;    
    item
      Title.Caption = 'ID'
      Width = 60
      FieldName = 'ID'
    end    
    item
      Title.Caption = 'DATESENT'
      FieldName = 'DATESENT'
    end    
    item
      Title.Caption = 'COURSE'
      Width = 140
      FieldName = 'COURSE'
    end    
    item
      Title.Caption = 'PROMOTYPE'
      Width = 140
      FieldName = 'PROMOTYPE'
    end    
    item
      Title.Caption = 'LINK'
      Width = 100
      FieldName = 'LINK'
    end    
    item
      Title.Caption = 'VALUE'
      Width = 50
      FieldName = 'VALUECHART'
    end    
    item
      Title.Caption = 'TOTALSENT'
      FieldName = 'TOTALSENT'
    end    
    item
      Title.Caption = 'NOTES'
      FieldName = 'NOTES'
    end&gt;
  DataSource = dsProgrammer
  TabOrder = 1
  OnTitleClick = dbgrdProgrammerTitleClick
  end
  object dbnavProgrammer: TDBNavigator
  Left = 280
  Height = 25
  Top = 376
  Width = 241
  BevelOuter = bvNone
  ChildSizing.EnlargeHorizontal = crsScaleChilds
  ChildSizing.EnlargeVertical = crsScaleChilds
  ChildSizing.ShrinkHorizontal = crsScaleChilds
  ChildSizing.ShrinkVertical = crsScaleChilds
  ChildSizing.Layout = cclLeftToRightThenTopToBottom
  ChildSizing.ControlsPerLine = 100
  ClientHeight = 25
  ClientWidth = 241
  DataSource = dsProgrammer
  Options = []
  TabOrder = 2
  VisibleButtons = [nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbRefresh]
  end
  object btnDeleteProgrammer: TButton
  Left = 64
  Height = 25
  Top = 376
  Width = 201
  Caption = 'Delete Selected Programmer'
  OnClick = btnDeleteProgrammerClick
  TabOrder = 3
  end
  object dsProgrammer: TDataSource
  DataSet = sqlqProgrammer
  left = 696
  top = 168
  end
  object IBConnection2: TIBConnection
  Connected = True
  LoginPrompt = False
  DatabaseName = '.......CONTRIBUTIONS.FDB'
  KeepConnection = False
  Password = 'password'
  Transaction = SQLTransaction2
  UserName = 'username'
  HostName = 'hostname'
  left = 696
  top = 8
  end
  object SQLTransaction2: TSQLTransaction
  Active = True
  Action = caCommitRetaining
  Database = IBConnection2
  left = 696
  top = 56
  end
  object sqlqProgrammer: TSQLQuery
  IndexName = 'DEFAULT_ORDER'
  FieldDefs = &lt;    
    item
      Name = 'ID'
      DataType = ftInteger
      Precision = -1
      Size = 0
    end    
    item
      Name = 'DATESENT'
      DataType = ftDate
      Precision = -1
      Size = 0
    end    
    item
      Name = 'PROMOTYPE'
      DataType = ftString
      Precision = -1
      Size = 25
    end    
    item
      Name = 'COURSE'
      DataType = ftString
      Precision = -1
      Size = 25
    end    
    item
      Name = 'LINK'
      DataType = ftString
      Precision = -1
      Size = 450
    end    
    item
      Name = 'VALUECHART'
      DataType = ftInteger
      Precision = -1
      Size = 0
    end&gt;
  Active = True
  Database = IBConnection2
  Transaction = SQLTransaction2
  SQL.Strings = (
    'select * from Programmer order by ID DESC'
  )
  UpdateSQL.Strings = (
    ''
  )
  InsertSQL.Strings = (
    ''
  )
  DeleteSQL.Strings = (
    ''
  )
  Params = &lt;&gt;
  UpdateMode = upWhereChanged
  UsePrimaryKeyAsKey = False
  left = 696
  top = 224
  end
  object SQLScript1: TSQLScript
  DataBase = IBConnection2
  Transaction = SQLTransaction2
  Directives.Strings = (
    'SET TERM'
    'COMMIT'
    '#IFDEF'
    '#IFNDEF'
    '#ELSE'
    '#ENDIF'
    '#DEFINE'
    '#UNDEF'
    '#UNDEFINE'
  )
  Script.Strings = (
    ''
  )
  Terminator = ';'
  CommentsinSQL = True
  UseSetTerm = True
  UseCommit = True
  UseDefines = True
  left = 696
  top = 112
  end
  end 
  </code></pre>
  
  <p>Thank you.</p>