GARANTIR DESCONTO

Fórum Nao ta funcionando o CancelUpdate (DBEXPRESS) #41242

30/12/2003

0

Olá nobres delphianos.
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

Pedih

Responder

Posts

30/12/2003

Afarias

O CancelUpdates não tem nada a ver com Transações. Ele apenas descarta as alterações no ´buffer´ (Delta) do ClientDataSet. Vc está misturando alterações feitas com ClientDataSets e processos executados direto no banco, em geral, esta não é uma boa prática -- sugiro q dê uma lida sobre tópicos relacionados a ClientDataSets.

Se deseja cancelar processos realizados no banco de dados, faça um ROLLBACK na transação.


T+


Responder

Gostei + 0

31/12/2003

Pedih

Caro Afarias.
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.


Responder

Gostei + 0

31/12/2003

Afarias

:shock:

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+


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar