Por que às vezes eu recebo uma exceção “Invalid transação objeto”?
Pergunta
Existe errado alguma coisa com esse código?
Às vezes eu recebo uma exceção não tratada "objeto de transação inválido" nele:
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;
Esta excepção está sendo levantada para o usuário, assim que eu supor que é levantada por RollbackFreeAndNil, uma vez que todos resto está dentro de um try..except.
Devo envoltório RollbackFreeAndNil com outro try..except? Que confusão.
Estou usando o Delphi 2009, DBX com Firebird 2.1 e motorista de Devart.
Solução 2
O problema é que SqlConnection.BeginTransaction retorna nil se SQLConnection não está conectada ao banco de dados. E então eu recebo a exceção de objeto de transação inválido.
Eu nunca esperava isso. Ele deve tentar se conectar ou levantar uma exceção. Retornando nil não faz sentido para mim.
Outras dicas
O que aconteceria se CommitFreeAndNil emitiu uma exceção?
RollbackFreeAndNil seria chamado. Será que TD ser válido, então?
Você está comendo a exceção, e, portanto, as evidências. Não faça isso; re-lance:
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;
algumas vezes é que você executar procedimentos varius com um componente como cxdbmemo e dar-lhe isso é erro. Você tem que remover esse componente (ou somthing como este) e fazer sua transação normal.
SQLConnection.DBXConnection.BeginTransaction(TDBXIsolations.ReadCommitted);