Why do I sometimes get an "Invalid transaction object" exception?

Is there anything wrong with this code? Sometimes I get an unhandled "Invalid transaction object" exception in it:

procedure BlaBla;
var
  TD: TDBXTransaction;
begin
  TD := SQLConnection.BeginTransaction;
  try
    SQLConnection.ExecuteDirect('some sql command');
    SQLConnection.ExecuteDirect('some sql command');
    SQLConnection.CommitFreeAndNil(TD);
  except
    SQLConnection.RollbackFreeAndNil(TD);
  end;
end;

      

This exception is thrown for the user, so I assume it was raised by the RollbackFreeAndNil command since everything else is inside try..except.

Should I wrap RollbackFreeAndNil with another try..except? What a mess.

I am using Delphi 2009, DBX with Firebird 2.1 and Devart drivers.

+1


source to share


4 answers


The problem is that SQLConnection.BeginTransaction returns nil if SQLConnection is not connected to the database. And then I get an invalid transaction object exception.



I never expected this. It should try to connect or throw an exception. Returning zero doesn't make sense to me.

+2


source


What happens if CommitFreeAndNil throws an exception?

RollbackFreeAndNil is called. Will TD be valid then?



You are eating an exception and therefore proof. Do not do this; re-cast:

procedure BlaBla;
var
  TD: TDBXTransaction;
begin
  TD := SQLConnection.BeginTransaction;
  try
    SQLConnection.ExecuteDirect('some sql command');
    SQLConnection.ExecuteDirect('some sql command');
  except
    SQLConnection.RollbackFreeAndNil(TD);
    raise;
  end;
  SQLConnection.CommitFreeAndNil(TD);
end;

      

+4


source


multiple times is when you run varius routines with a component like cxdbmemo and you get this error. You should remove this component (or something similar) and make the transaction normal.

+1


source


SQLConnection.DBXConnection.BeginTransaction(TDBXIsolations.ReadCommitted);

      

0


source







All Articles