Fórum Nao ta funcionando o CancelUpdate (DBEXPRESS) #41242
30/12/2003
0
Vejam o meu problema : Estou realizando Entrada de produtos, entao, atualizo Movimento do Estoque e o Produto.
primeiro, realizo a transacao no movimento, logo em seguida, no produto.
Só que, ja fiz o teste, se der um erro na transacao em produto (2 transacao), mesmo realizando um CancelUpdate, ele ta gravando na base de dados, o que ta errado?
Grato.
====
estou utilizando : DBEXPRESS.
TSQLConnection, TSQLDataSet, TDataSetProvider, TClientDataSet, TDataSource, TSQLQuery.
:shock:
Falhou := False;
try
dm.sqlMvtEstoqueUPG.SQL.Text := SQLTextMvt; -> componente TSQLQuery
dm.sqlProdutoUPG.SQL.Text := SQLTextProd;
dm.sqlMvtEstoqueUPG.ExecSQL;
dm.sqlProdutoUPG.ExecSQL;
dm.tbMvtEstoque.Open; -> componente TClientDataSet
dm.tbProdutos.Open; idem componente
dm.tbMvtEstoque.ApplyUpdates(0);
dm.tbProdutos.ApplyUpdates(0);
StatusBar1.Panels[0].Text := ´ Transação Efetuada´;
except
dm.tbMvtEstoque.Open;
dm.tbProdutos.Open;
dm.tbMvtEstoque.CancelUpdates;
dm.tbProdutos.CancelUpdates;
Falhou := True;
end;
dm.tbMvtEstoque.Close;
dm.tbProdutos.Close;
dm.sqlMvtEstoqueUPG.Close;
dm.sqlProdutoUPG.Close;
dm.tbGrupo.Close;
dm.tbMarca.Close;
dm.tbUnidade.Close;
DecimalSeparator := ´,´;
if Falhou then
begin
StatusBar1.Panels[0].Text := ´ Falha na Transação...´;
MessageDlg(´Não foi possível Efetuar a Transação´,mtError, [mbok], 0);
Exit;
end
else
MessageDlg(´Lançamento Efetudado...´+#13+
´Estoque já foi atualizado !´, mtInformation, [mbok], 0);
valeu,
grato pela costumeira atencao de todos.
Pedih
Curtir tópico
+ 0Posts
30/12/2003
Afarias
Se deseja cancelar processos realizados no banco de dados, faça um ROLLBACK na transação.
T+
Gostei + 0
31/12/2003
Pedih
de acordo com sua resposta acima, pesquisei e montei a seguinte rotina :
====== ESTA É UMA ROTINA GENÉRICA, SERVIRÁ PARA QUALQUER APPLYUPDATE DE QUALQUER TClientDataSet =======
function Tdm.ApplyUpdateDs(DataSetA:array of TClientDataSet; BarraStatus : TStatusBar) : Boolean;
var
TransDesc : TTransactionDesc;
i, j : Integer;
begin
Result := False;
try
// APLICAR UPDATE
TransDesc.TransactionID := 1;
TransDesc.IsolationLevel := xilREADCOMMITTED;
for i := 0 to ComponentCount-1 do
begin
if Components[i] is TClientDataSet then
for j := low(DataSetA) to high(DataSetA) do
if UpperCase(Components[i].Name) = UpperCase(DataSetA[j].Name) then
begin
if not Conexao.InTransaction then
Conexao.StartTransaction(TransDesc);
DataSetA[j].ApplyUpdates(-1);
end;
end;
// COMMITAR AGORA
Conexao.Commit(TransDesc);
BarraStatus.Panels[0].Text := ´ Transação Efetuada...´;
Result := True;
except
Conexao.Rollback(TransDesc);
BarraStatus.Panels[0].Text := ´ Transação não obteve êxito...´;
ShowMessage(´Problemas na gravação dos dados! ´);
Result := False;
end;
end;
chamo essa funça da seguinte maneira :
with dm do
begin
sqlGrupoUPG.ExecSQL;
tbGrupo.Open;
ApplyUpdateDs([tbGrupo], StatusBar1);
tbGrupo.Close;
sqlGrupoUPG.Close;
end;
=== qdo passa apenas uma tabela, funciona 100¬.
agora, passando mais de 1 tabela.
sqlMvtEstoqueUPG.SQL.Text := SQLTextMvt;
sqlProdutoUPG.SQL.Text := SQLTextProd;
sqlMvtEstoqueUPG.ExecSQL;
sqlProdutoUPG.ExecSQL;
tbMvtEstoque.Open;
// tbProdutos.Open; === linha em destaque.
ApplyUpdateDs([tbMvtEstoque, tbProdutos], StatusBar1);
obs: coloquei de proposito essa linha // tbProdutos.Open;
para poder gerar um erro na rotina generica, o que deveria acontecer,
ele aplica um applyupdate em tbMvtEstoque, depois, quando chega para dar o applyupdate em tbProdutos, sera gerado um erro, cairá no except da rotina. Ele tá caíndo lá, perfeitamente, só que a linha :
Conexao.Rollback(TransDesc);
nao tá desfazendo nada no banco. Sinceramente, nao sei o que poderia ser...
====== IMPORTANTE ====
A rotina está 100¬, caso nao haja um Except, ele atualiza (applyupdate) perfeitamente, independente de qtas tabelas sejam passadas via parametros. O problema esta apenas em ROLLBACK.
== peguei este exemplo na net.
var
> DescTransacao: TTransactionDesc;
> begin
> DescTransacao.TransactionID := 1;
> DescTransacao.IsolationLevel := xilREADCOMMITTED;
> SQLConnection1.StartTransaction(DescTransacao);
> try
> SimpleDataSet1.ApplyUpdates(-1);
> SimpleDataSet2.ApplyUpdates(-1);
> SimpleDataSet3.ApplyUpdates(-1);
> SQLConnection1.Commit(DescTransacao);
> except
> SQLConnection1.Rollback(DescTransacao);
> end;
>
Grato e muito obrigado pela atencao.
Gostei + 0
31/12/2003
Afarias
Humm... olha... muito ´esquisita´ essa função ApplyUpdateDs... Alguns equívocos nesta função::
1) Em geral vc NUNCA abre uma transação para o ClientDataSet -- o MIDAS faz tudo automático.
2) ApplyUpdates NUNCA gera exceções! Um try/except não faz o menor sentido ai... Vc deve verificar o retorno da função ou usar o evento OnReconcileError (além de outros métodos)
3) Da mesma forma q vc não abre a transação, vc tb não fecha!! um commit ou rollback é desnecessário!! -- Entretanto vc pode optar por abrir e fechar manualmente, mas não use um TRY/EXCEPT para isso!
Além do mais, existe algo estranho não relacionado ao uso de ClientDataSets... é o Loop! que deveria ser apenas::
for i := low(DataSetA) to high(DataSetA) do with DataSetA[I] do begin // processo... end;
não entendo pq compara com o Components[x]
o ´processo´ no seu código poderia ser apenas (para mim)::
if ApplyUpdates(0) > 0 then BarraStatus.Panels[0].Text := ´Erro gravando dados.´ else BarraStatus.Panels[0].Text := ´Gravação realizada com sucesso.´;
e sobre o código abaixo::
[code]
with dm do
begin
sqlGrupoUPG.ExecSQL;
tbGrupo.Open;
ApplyUpdateDs([tbGrupo], StatusBar1);
tbGrupo.Close;
sqlGrupoUPG.Close;
end;
[code]
Não entendi o q ele faz!! Não tá fazendo o menor sentido para mim!! Vc executa algo, abre o CDS, dá o ApplyUpdates (sem ter feito nada nele!!!!!!!) e depois fecha!!! :?
Quanto ao seu problema citado (ao cair no EXCEPT devido ao CDS não estar aberto, o ROLLBACK ´não funciona´) ... veja, como disse na mensagem anterior:: vc está misturando processos com CDS... as coisas não estão muito claras, nem com relação as transações de cada caso... mas, pra mim, não é surpresa q algo não esteja funcionando!!
Se vc está executando algo, antes de abrir a transação na função, é pq alguma transação já está aberta, não sei se a mesma.
Esses processos tem q ser rodados na mesma transação do ClientDataSets ou mesmo juntos??? Pq??
Veja, ClientDataSets são ótimos, mas é preciso entender como funcionam -- veja se vc consegue algum material sobre o assunto ou mesmo leia o help/manuais do Delphi ou o material na Borland.com.
T+
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)