Fórum Controlando erros em uma venda para evitar inconsistências #248849
31/08/2004
0
Quando eu gravo uma venda, faço alterações em várias tabelas (na própria venda, no produtos, ctas receber, etc).
Os últimos comandos da rotina de gravação da venda são assim:
try
EstoqueProdutos. ApplyUpdates(0);
ContasReceber.ApplyUpdates(0);
VendaMestre.ApplyUpdates(0);
except
ShowMessage(´ocorreu um erro´);
Até aqui tudo certo. Agora vem minha dúvida/problema: na rotina acima, dentro do try, há três comandos. Se o primeiro comando (EstoqueProdutos.Appp...) der erro, nada é gravado. Mas e se por exemplo, ocorrer um erro no no último comando dentro do try (VendaMestre.app...), as outras duas tabelas teriam sido alteradas indevidamente, pois a venda não foi gravada devido ao erro.
Pergunto: como controlar isso? Como ficaria uma rotina correta para isso?
Obrigado
Valdirdill
Curtir tópico
+ 0Posts
31/08/2004
Macario
Bom não manjo muito de SQL, mas procure no forum topicos sobre Transações. Toda essa rotina de gerar a nota deve ficar dentro de uma transação, assim se em algum ponto houver falha será aplicado um rollback em tudo.
E aguarde mais explicações dos nossoa colegas.
Gostei + 0
31/08/2004
Xtreme
EstoqueProdutos. ApplyUpdates(0);
ContasReceber.ApplyUpdates(0);
VendaMestre.ApplyUpdates(0);
except
ShowMessage(´ocorreu um erro´);
[b:66d371307e]transaction.rollback;[/b:66d371307e]//desta forma vc digamos assim cancela toda e qualquer alteracao feita no banoc de dados
end;
Gostei + 0
31/08/2004
Xtreme
Obs.: o transaction é um componente ex.: IBTransaction (na paleta do interbase).
Gostei + 0
31/08/2004
Vinicius2k
Existem 2 problemas :
1. Se não houver controle explícito de transação muita coisa pode dar errado. O que for aplicado sem erros não é desfeito, pois está existindo uma transação diferente para cada ApplyUpdates...
2. O método ApplyUpdates NUNCA gera exceção para erros vindos do banco de dados... então try/except não resolve.
O que vc precisa fazer é controlar a transação e verificar sempre o valor de retorno do método ApplyUpdates (ele retorna o número de erros ocorridos na tentativa de aplicação)...
Um exemplo seria :
var
TudoOK: Boolean;
TD: TransactionDesc;
try
TudoOK:= False;
TD.TransactionID:= 1;
TD.IsolationLevel:= xilReadCommitted;
SQLConnection1.StartTransaction(TD);
{****}
if EstoqueProdutos.ApplyUpdates(0) = 0 then
if ContasReceber.ApplyUpdates(0) = 0 then
if VendaMestre.ApplyUpdates(0) = 0 then
TudoOK:= True;
{****}
if TudoOK then SQLConnection1.Commit(TD)
else
begin
ShowMessage(´Ocorreram erros !´);
SQLConnection1.Rollback(TD);
end;
except
On E: Exception do
ShowMessage(´Não foi possível abrir a transação.´ + #13 + E.Message);
end;Vc pode fazer uma pesquisa aqui no fórum sobre Transação + dbExpress q vc terá outros exemplos... veja tbm este tópico recente: http://delphiforum.icft.com.br/forum/viewtopic.php?t=50822
Espero ter ajudado...
T+
Gostei + 0
31/08/2004
Xtreme
Gostei + 0
31/08/2004
Vinicius2k
Commit(TD) : o record ´TD´ tem a ´TransactionID´ que identifica a transação que vc quer dar start, commit ou rollback, mas isto só vale para dbExpress pq a SQLConnection suporta várias transações simultâneas...
Se vc estiver usando IBX e quiser trabalhar com múltiplas transações simultâneas, precisa de múltiplos IBTransactions... OK?
T+
Gostei + 0
31/08/2004
Xtreme
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)