Duplicate Transaction ID
30/08/2004
0
Procurei por soluções mas não encontrei.
Estou usando Firebird 1.5 Delphi 7 e Dbexpress.
Obrigado
Fabio
Henry.fartura
Posts
30/08/2004
Vinicius2k
Vc está abrindo uma transação com a mesma ID de uma transação anterior que ainda está aberta (sem commit ou rollback)... Vc pode repetir IDs para as transações, mas a anterior de mesma ID tem que ter sido fechada...
Vc vai ter q depurar seu código em busca dessa transação que, por algum motivo, está ficando aberta...
T+
31/08/2004
Henry.fartura
As transações que você me citou seria o caso de eu dar um insert duas vezes na mesma tabela?
Pois não estou entendendo o que você quis dizer com transações...
O DBexpress não faz isso automático no arquivo dbxconnections?
Bom, se puder me ajudar eu agradeço...
OBS: Este erro só me aconteceu uma vez até agora... mas quero entender o porque.
31/08/2004
Vinicius2k
O que eu quis dizer com ´transação´ é realmente o controle explícito das transações que pode ser feito com :
SQLConnection.StartTransaction(Transacao); SQLConnection.Commit(Transacao); SQLConnection.Rollback(Transacao);
Essa variável ´Transacao´ precisa receber um ´ID´ e depois de iniciada a transação, o mesmo ID só pode ser usado novamente se a transação anterior for fechada com commit ou rollback...
Um exemplo de controle explícito, soh para vc compreender do que se trata :
... var Transacao: TTransactionDesc; begin Transacao.TransactionID:= 1; Transacao.IsolationLevel:= xilReadCommitted; SQLConnection1.StartTransaction(Transacao); if ClientDataSet1.ApplyUpdates(0) = 0 then begin SQLConnection1.Commit(Transacao); ShowMessage(´Registro salvo OK.´); end else begin SQLConnection1.Rollback(Transacao); ShowMessage(´Ocorreram erros... alterações desfeitas.´); end; end;
Nesta linha : Transacao.TransactionID:= 1; , eh que não pode ser atribuída a ID ´1´ para outra transação enquanto a ID ´1´ atual não for fechada...
Mas, pelo que vc disse, vc não está fazendo controle de transações, então acho q vc pode desconsiderar o que eu disse...
Quando vc não faz o controle explícito que eu mostrei acima, a própria midas.dll o faz, então quando vc chama ´ClientDataSet1.ApplyUpdates(0)´ a midas abre uma transação para esta operação automaticamente e se correr tudo bem é dado o commit ou se der algo errado um rollback... é tudo automático... na verdade o controle acima só é útil para utilização de 2 ou mais ApplyUpdates que são ´dependentes´ como um mestre/detalhe, por exemplo, como a midas vai criar uma transação para cada ApplyUpdates, se algo der errado no 2º ela não vai desfazer o 1º... ao passo que se vc controlar externamente, em qualquer um que ocorrer erro vc pode desfazer tudo, mantendo as informações na base consistentes...
Já que o erro só ocorreu uma vez, fica difícil imaginar o que houve, até mesmo pelo fato de não estar existindo o controle da transação por vc... precisaria haver um padrão de onde e quando o erro ocorre para que possamos ajudá-lo... a não ser que outro colega já tenha passado por isso, pq eu, até o momento não...
T+
31/08/2004
Henry.fartura
tipo assim, o apply updates do detalhe deu erro.
mas é muito estranho, pois eu não deixo o usuario dar um insert ou edit no clientdataset detalhe se o clientdataset mestre também estiver em modo de inserção ou edição.
Ja intendi bem como funciona essa transação manual.
Obrigado pela ajuda...
Agora outra dúvida.
Se eu tiver 2 usuarios no mesmo registro, aquele que der um edit primeiro e se eu tiver usando essa transação manual q vc me explicou, qdo o segundo usuario der edit ele ñ vai conseguir?
pq do jeito normal como eu trabalho, os 2 usuarios podem dar o edit, porém quem der o applyupdates por ultimo eu mostro uma caixa de dialogo do handlereconcileerror.
Vc trabalha como?
31/08/2004
Vinicius2k
Não muda nada... nada mesmo... vc pode continuar usando o form de reconcile normalmente... controlar a transação manualmente é como se vc disesse para a midas : ´Olha midas, deixa comigo que esta parte do código eu quero controlar tudo... o que vai ser feito ou desfeito e como ou quando vai ser feito ou desfeito...´
Vc apenas inibe o processo automático, pq se vc tem dois ou mais ApplyUpdates em sequencia, a midas não vai analisar seu código e pensar ´Eu não vou fechar esta transação agora, pq tem mais um ApplyUpdates ´alí embaixo´ e algo pode dar errado...´
Não costumo permitir interação do usuário em relação à erros de reconciliação... quando ocorre algum erro, eu mostro-lhe o erro (os mais comuns personalizados), cancelo os updates e desfaço tudo o que ele fez... atualizo o CDS e se ele quiser, que faça novamente... Com o perfil de usuários com os quais eu lido diariamente, infelizmente, não posso permitir que tomem decisões... permitir q um usuário meu tome uma decisão é arranjar ´dor de cabeça´ com o cliente... mas cada caso eh um caso... seus usuários podem ser diferentes ( tomara que sejam :D )...
Em situações críticas onde, nada pode dar errado, tranco o registro selecionado para edição, e ninguém mais pode trabalhar nele enquanto quem trancou não terminar (alguns segundos apenas ou menos que isso)... mas isso só em casos críticos mesmo... É muito importante também manter as transações ´curtas´ : Abre -> Aplica os updates -> Fecha (commit ou rollback)... isso ajuda muito o bom fluxo da aplicação e dimunui a margem de problemas... na verdade, quando vc deixa no automático é assim que a midas trabalha...
T+
Clique aqui para fazer login e interagir na Comunidade :)