DBExpress - Transaction no Active
Pessoal me ajudem por favor!,
Estou usando Delphi 7 e Firebird 2.1 e estou com o seguinte problema:
Na minha tela de cadastro, quando faço inserçao blz, se por ventura eu quiser excluir o cliente ou fechar a tela de cadastro está dando um erro "Transaction no Active".
O Código no no botão excluir é esse:
{: deleta se houver dados no DataSet }
if (DataSource1.DataSet.Active) and (DataSource1.DataSet.RecordCount > 0) then
begin
if MessageDlg('Tem certeza que deseja excluir o registro ?', mtConfirmation, [mbYes,mbNo], 0) = mrYes then
DataSource1.DataSet.Delete;
DataSource1.DataSet.Open;
end;
EnableDisableControls(False);
if (DataSource1.DataSet.Active) and (DataSource1.DataSet.RecordCount > 0) then
begin
if MessageDlg('Tem certeza que deseja excluir o registro ?', mtConfirmation, [mbYes,mbNo], 0) = mrYes then
DataSource1.DataSet.Delete;
DataSource1.DataSet.Open;
end;
EnableDisableControls(False);
Josenildo Rosa
Curtidas 0
Respostas
Marco Salles
17/03/2011
Pessoal me ajudem por favor!,
Estou usando Delphi 7 e Firebird 2.1 e estou com o seguinte problema:
Na minha tela de cadastro, quando faço inserçao blz, se por ventura eu quiser excluir o cliente ou fechar a tela de cadastro está dando um erro "Transaction no Active".
O Código no no botão excluir é esse:
{: deleta se houver dados no DataSet }
if (DataSource1.DataSet.Active) and (DataSource1.DataSet.RecordCount > 0) then
begin
if MessageDlg('Tem certeza que deseja excluir o registro ?', mtConfirmation, [mbYes,mbNo], 0) = mrYes then
DataSource1.DataSet.Delete;
DataSource1.DataSet.Open;
end;
EnableDisableControls(False);
if (DataSource1.DataSet.Active) and (DataSource1.DataSet.RecordCount > 0) then
begin
if MessageDlg('Tem certeza que deseja excluir o registro ?', mtConfirmation, [mbYes,mbNo], 0) = mrYes then
DataSource1.DataSet.Delete;
DataSource1.DataSet.Open;
end;
EnableDisableControls(False);
Eu não entendi porque esta open depois do delete ???
por acaso qnd vc dar o delete o clientDataSet não esta aberto ??? Se tiver fechado não geraria um erro ???
GOSTEI 0
Josenildo Rosa
17/03/2011
Marcos para te falar a verdade não sei te explicar direito pois o meu form modelo eu peguei pronto da video aula do luciano pimenta, acontece que ele usa uma variavel conforme descrita abaixo:
private
{ Private declarations }
public
{ Public declarations }
Transc: TTransactionDesc; ------------------------ esse transc no qual me refiro
procedure Start; ----------------------- uso na minha aplicacao na hora de salvar store procedures, que no inicio eu starto ela e depois no final eu comito.
procedure Comit;
procedure Rollback ; ========================= para cada procedure uso o seguinte: procedure TDM.Comit;
begin
Conexao.Commit(Transc);
end; procedure TDM.Rollback;
begin
Conexao.Rollback(Transc);
raise Exception.Create(MSG_ERRO);
end; procedure TDM.Start;
begin
Transc.IsolationLevel := xilREADCOMMITTED;
Transc.TransactionID := StrToInt(IDTransaction);
Conexao.StartTransaction(Transc);
end;
{ Private declarations }
public
{ Public declarations }
Transc: TTransactionDesc; ------------------------ esse transc no qual me refiro
procedure Start; ----------------------- uso na minha aplicacao na hora de salvar store procedures, que no inicio eu starto ela e depois no final eu comito.
procedure Comit;
procedure Rollback ; ========================= para cada procedure uso o seguinte: procedure TDM.Comit;
begin
Conexao.Commit(Transc);
end; procedure TDM.Rollback;
begin
Conexao.Rollback(Transc);
raise Exception.Create(MSG_ERRO);
end; procedure TDM.Start;
begin
Transc.IsolationLevel := xilREADCOMMITTED;
Transc.TransactionID := StrToInt(IDTransaction);
Conexao.StartTransaction(Transc);
end;
GOSTEI 0
Marco Salles
17/03/2011
entendi ..
Acho que qnd vc esta comitando , ele ja destroe a transação e depois vc da um Rooback num objeto inválido
procedure Comit;
procedure Rollback ; geralmente se usa um bloco protegido para que caso de algum erro ele vai para o Rooback try blocos excpet Roolback Porém se vc tiver utilizando o delphi 2010 existe uma nova classe de transação que evita este tipo de problema Ou seja , ele testa o "objeto" antes de dar o Roolback.
procedure Rollback ; geralmente se usa um bloco protegido para que caso de algum erro ele vai para o Rooback try blocos excpet Roolback Porém se vc tiver utilizando o delphi 2010 existe uma nova classe de transação que evita este tipo de problema Ou seja , ele testa o "objeto" antes de dar o Roolback.
GOSTEI 0
Josenildo Rosa
17/03/2011
Mas no meu caso que uso Delphi 7, como que vou resolver esse problema ?
GOSTEI 0
Marco Salles
17/03/2011
Ai vc tem que usar o Try Except
Assim
var tr:TTransactionDesc; begin tr.TransactionId:=1; tr.IsolationLeve:=xilReadCommited; Conexao.StartTransaction(tr); try Seu comandos de Indert , delete , Update etc.. Conexao.coomit(tr); except conexao.Roolback(tr); end; end;
GOSTEI 0
Josenildo Rosa
17/03/2011
mas marcos, esse procedimento é o que eu estou usando atualmente.
GOSTEI 0
Marco Salles
17/03/2011
mas marcos, esse procedimento é o que eu estou usando atualmente.
sim mas vc deve estar usando de modo equivocado. Porque o erro parece é que vc esta tentando Comitar uma Transação que não existe ou mesmo desfazer uma Transação que não existe . Vamos imaginar que ve esteja utilizando
este procedimento. Ai vc Da um Start , faz operação e comita. Ai para iniciar um Novo processo tem que start Novamente e apos isto um Commit ou um Roolback
Verifique a sua rotina de instruçoes para descobrir onde esta o gargalho que esta causando esta mensagem
GOSTEI 0
Josenildo Rosa
17/03/2011
O procedimento que uso para salvar é este:
procedure TDM.cdsProdutoBeforePost(DataSet: TDataSet);
begin
{: insere ou atualiza Produtos }
Start; -------> que é aquela que comentei anteriormente
try
with spProduto do
begin
Params[0].AsInteger := cdsProdutoP_ID.AsInteger;
Params[1].AsInteger := cdsProdutoF_ID.AsInteger;
Params[2].AsString := cdsProdutoP_NOME.AsString;
Params[3].AsString := cdsProdutoP_UN.AsString;
Params[4].AsInteger := cdsProdutoP_QTD.AsInteger;
Params[5].AsString := cdsProdutoP_REF.AsString;
Params[6].AsString := cdsProdutoP_COR.AsString;
Params[7].AsString := cdsProdutoP_TAM.AsString;
Params[8].AsBCD := cdsProdutoP_CUSTO.AsCurrency;
Params[9].AsBCD := cdsProdutoP_VENDA.AsCurrency;
ExecProc;
Comit; -------> que é aquela que comentei anteriormente
end;
except
Rollback; -------> que é aquela que comentei anteriormente
end; ------------ neste caso vc me aconcelha colocar start aqui novamente ?
end;
begin
{: insere ou atualiza Produtos }
Start; -------> que é aquela que comentei anteriormente
try
with spProduto do
begin
Params[0].AsInteger := cdsProdutoP_ID.AsInteger;
Params[1].AsInteger := cdsProdutoF_ID.AsInteger;
Params[2].AsString := cdsProdutoP_NOME.AsString;
Params[3].AsString := cdsProdutoP_UN.AsString;
Params[4].AsInteger := cdsProdutoP_QTD.AsInteger;
Params[5].AsString := cdsProdutoP_REF.AsString;
Params[6].AsString := cdsProdutoP_COR.AsString;
Params[7].AsString := cdsProdutoP_TAM.AsString;
Params[8].AsBCD := cdsProdutoP_CUSTO.AsCurrency;
Params[9].AsBCD := cdsProdutoP_VENDA.AsCurrency;
ExecProc;
Comit; -------> que é aquela que comentei anteriormente
end;
except
Rollback; -------> que é aquela que comentei anteriormente
end; ------------ neste caso vc me aconcelha colocar start aqui novamente ?
end;
GOSTEI 0
Marco Salles
17/03/2011
este codigo esta " certo " na Inclusão do cliente
Mas e na Exlusão .. Vc relatou o problema na exclusão
O que vc Esta fazendo
GOSTEI 0
Josenildo Rosa
17/03/2011
é o mesmo praticamente, so muda o comando.
procedure TDM.cdsProdutoBeforeDelete(DataSet: TDataSet);
begin
{: exclui Produtos }
Start;
try
with spProdutoD do
begin
Params[0].AsInteger := cdsProdutoP_ID.AsInteger;
ExecProc;
Comit;
end;
except
Rollback;
end;
end;
begin
{: exclui Produtos }
Start;
try
with spProdutoD do
begin
Params[0].AsInteger := cdsProdutoP_ID.AsInteger;
ExecProc;
Comit;
end;
except
Rollback;
end;
end;
GOSTEI 0
Marco Salles
17/03/2011
entendi.. Então é o seguinte. O processo esta certo . A idéia é esta. Talves seje o evento
Vc coloca alguma coisa no AfterDelete ou AfterInsert ???
GOSTEI 0
Josenildo Rosa
17/03/2011
Não, eu não uso nada no afterpost e nem no afterdelete
GOSTEI 0
Josenildo Rosa
17/03/2011
Marcos, Consegui resolver o meu problema,
aproveitando a situação deste post, gostaria de saber se vc tem algum exemplo de como imprimir etiquetas pimaco atraves do delphi. meu email é josenildo.rui@gmail.com e o msn: josenildo_rui@hotmail.com
Desde já quero agradecer pela paciência e pela força que tem me dado neste problema.
Muito obrigado
Fica com Deus.
GOSTEI 0
Marco Salles
17/03/2011
Marcos, Consegui resolver o meu problema,
aproveitando a situação deste post, gostaria de saber se vc tem algum exemplo de como imprimir etiquetas pimaco atraves do delphi. meu email é josenildo.rui@gmail.com e o msn: josenildo_rui@hotmail.com
Desde já quero agradecer pela paciência e pela força que tem me dado neste problema.
Muito obrigado
Fica com Deus.
Beleza
Mas vamos com calma
Onde vc estava errando.. Post ai < deve ser alguma coisa simples >
por acaso vc mudou de evento.. ???
GOSTEI 0
Josenildo Rosa
17/03/2011
Não, não mudei nenhum evento, apenas tirei, a linha de comando DM.IBTRANS.COMMIT do onClose do Form,
Pois eu estava usando o DBExpress e o IBInterbase. Erro meu mesmo, vacilei.
GOSTEI 0