Why sometimes I get an “Invalid transaction object” exception?
Question
Is there something 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 being raised to the user, so I assume it's raised by RollbackFreeAndNil, since all rest is inside a try..except.
Should I wrap RollbackFreeAndNil with another try..except? What a mess.
I'm using Delphi 2009, DBX with Firebird 2.1 and Devart's driver.
Solution 2
The problem is that SQLConnection.BeginTransaction returns nil if SQLConnection is not Connected to the database. And then I get the exception of invalid transaction object.
I never expected that. It should try to connect or raise an exception. Returning nil doesn't make sense to me.
OTHER TIPS
What would happen if CommitFreeAndNil threw an exception?
RollbackFreeAndNil would be called. Would TD be valid then?
You're eating the exception, and hence the evidence. Don't do that; re-throw:
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;
some times is that you execute varius procedures with a component like cxdbmemo and give you thats error. You have to remove that component (or somthing like this) and do your transaction normal.
SQLConnection.DBXConnection.BeginTransaction(TDBXIsolations.ReadCommitted);