Ir para conteúdo
  • Cadastre-se

dev botao

Firedac não grava às vezes


Ver Solução Respondido por Juliomar Marchetti,
  • Este tópico foi criado há 1739 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Usava o XE6 com Firebird 2.1 e tudo estava ok.

Resolvi trocar pelo Firedac para poder atualizar o Firebird e nos normais antes da implantação foi tudo ok.

Agora vira e mexe aparece usuário reclamando que fez isso ou aquilo, está no seu computador mas não no de outra pessoa.

Nem estou usando transactions nem cache updates. Um simples pool de insert's ou update's fica como efetivado no local somente para este usuário e às vezes quando ele fecha o programa atualiza outras vezes não.

 

Tem algum commit que deve ser dado ou parâmetro que deva ser utilizado?

 

Grato por qualquer ajuda.

Link para o comentário
Compartilhar em outros sites

Tente fazer dessa forma, e faça os testes, veja se a informação e gravada no banco;

procedure TForm1.btn_DBTransClick(Sender: TObject);
begin
  FDConnection1.Transaction.StartTransaction ;

  try

    { TSQL }
    FDConnection1.Transaction.Commit ;
  except
    FDConnection1.Transaction.Rollback ;
  end;
end;

 

Sistema de Automação Comercial para diversos segmentos
NF-e, NFC-e, SPED Fiscal - www.arenasoft.com.br

Link para o comentário
Compartilhar em outros sites

Em 30/08/2017 at 00:23, Solivan disse:

Tente fazer dessa forma, e faça os testes, veja se a informação e gravada no banco;

procedure TForm1.btn_DBTransClick(Sender: TObject);
begin
  FDConnection1.Transaction.StartTransaction ;

  try

    { TSQL }
    FDConnection1.Transaction.Commit ;
  except
    FDConnection1.Transaction.Rollback ;
  end;
end;

 

Agradeço a sugestão Solivan, mas acho estranho supostamente ser forçado a usar transactions se um um simples update direto fica "suspenso" sem solicitação (com o Zeos não tinha esse problema, se eu dava um update xyz ele era efetuado - desde que sem concorrência logicamente - e fim de papo). Agora vira e mexe os usuários precisam fechar o sistema para uma atualização ser feita ou um deadlock ocorre sem que nenhuma transação tenha sido iniciada.

 

Outra coisa bizarra que ocorre é num "while not eof" com uma sequência de dados, se "next" ultrapassa o rowlimit do fetch o eof fica true ainda que existam mais registros na busca...

 

Se arrependimento matasse...

 

Link para o comentário
Compartilhar em outros sites

20 horas atrás, OldProgramer disse:

Agradeço a sugestão Solivan, mas acho estranho supostamente ser forçado a usar transactions se um um simples update direto fica "suspenso" sem solicitação (com o Zeos não tinha esse problema, se eu dava um update xyz ele era efetuado - desde que sem concorrência logicamente - e fim de papo). Agora vira e mexe os usuários precisam fechar o sistema para uma atualização ser feita ou um deadlock ocorre sem que nenhuma transação tenha sido iniciada.

 

Outra coisa bizarra que ocorre é num "while not eof" com uma sequência de dados, se "next" ultrapassa o rowlimit do fetch o eof fica true ainda que existam mais registros na busca...

 

Se arrependimento matasse...

 

Eu tentei migrar de ado pra firedac não deu muito certo, então testei o Unidac e achei muito bom, inclusive nos testes ganha do firedac no desempenho, acho que compensa você migrar pra UniDac, utilizo ele em todas as aplicações inclusive android pra fazer conexões diretas ao banco sem necessidade de carga de dados(em rede local).

Sistema de Automação Comercial para diversos segmentos
NF-e, NFC-e, SPED Fiscal - www.arenasoft.com.br

Link para o comentário
Compartilhar em outros sites

  • 7 meses depois ...

Cara eu tive bastante problemas com Commit no Firedac (com Firebird). Como não era um projeto com muitos terminais nem muitas movimentações eu resolvi com uma solução que acredito não ser das melhores.

Crie um componente do tipo TFDTransaction e ligue no seu componente TFDConnection (Propriedade Transaction e UpdateTransaction)

No Evento do Seu TFDConnection  =  AfterCommit coloque:

    if FDTransaction1.Active then try
      FDTransaction1.Commit;
    except
    end;

No Evento do Seu TFDTransaction Coloque:

    try
       if (not debugando)or(database1.intransaction) then
         database1.Commit;
    except
    end;
    if FDTransaction1.Active then try
      FDTransaction1.Commit;
    except
    end;

A varíavel "Debugando" que criei de nivel global recebe "True" se achou algum arquivo PAS na pasta de execução. Fiz isso porque se não fica dando erro ao DEBUGAR, mas pode tirar a condição dela se quiser ficando apenas " if (database1.intransaction) then"

E ainda teve uma janela do sistema que tiver que ligar os TABLES em um outro FDTransaction separado e colocar este mesmo evento (acima) no FDTransaction (mas o mesmo FDConnection).

Resolveu 99,9% dos problemas deste projeto e vários terminais alterando ao mesmo tempo. Se possível entre as opções do menu feche seu FDConnection que ai os commits vão direto para base.

No UpdateOptions dos meus objetos de conexão, base e query ... deixei AutoCommitUpdates TRUE, LockMode lmPessimistic, LockPoint lpDeferred, RefreshMode rmAll e UpdateMode upWhereKeyOnly. Também não sei se são a melhor opção para você, mas pode tentar.

Se alguém tiver outra solução, mas realmente complicado o Firedac.

Abraço a todos.

Editado por Sergio Augusto
Link para o comentário
Compartilhar em outros sites

  • 3 semanas depois ...
Em 29/08/2017 at 16:43, OldProgramer disse:

Usava o XE6 com Firebird 2.1 e tudo estava ok.

Resolvi trocar pelo Firedac para poder atualizar o Firebird e nos normais antes da implantação foi tudo ok.

Agora vira e mexe aparece usuário reclamando que fez isso ou aquilo, está no seu computador mas não no de outra pessoa.

Nem estou usando transactions nem cache updates. Um simples pool de insert's ou update's fica como efetivado no local somente para este usuário e às vezes quando ele fecha o programa atualiza outras vezes não.

 

Tem algum commit que deve ser dado ou parâmetro que deva ser utilizado?

 

Grato por qualquer ajuda.

Também passo por este problema. Já tentei de tudo, mas de vez em quando aparece um caso. Algum de vocês resolveu?

Link para o comentário
Compartilhar em outros sites

21 horas atrás, datilas disse:

eu resolvi assim:

 If Not FDConnection1.InTransaction Then
  FDConnection1.StartTransaction;
   ...
 If Not FDConnection1.InTransaction Then
  FDConnection1.CommitRetaining;

 

Oi, datilas, blz! Não entendi onde colocou esses comandos, poderia me explicar? Apenas isso resolveu, ou teve que alterar alguma configuração no componente de conexão?

Link para o comentário
Compartilhar em outros sites

  • Moderadores

Bom dia

acho que a primeira coisa é entender como funciona e quando usar as transações.

lá na wiki da embacadero tem todo detalhado o processo já chegaram a ler.?

http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/FireDAC.Transactions_Sample

http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Managing_Transactions_(FireDAC)

 

Consultor SAC ACBr Juliomar Marchetti
 

Projeto ACBr

skype: juliomar
telegram: juliomar
e-mail: [email protected]
http://www.juliomarmarchetti.com.br
MVP_NewLogo_100x100_Black-02.png
 

 

Link para o comentário
Compartilhar em outros sites

7 minutos atrás, Juliomar Marchetti disse:

Bom dia

acho que a primeira coisa é entender como funciona e quando usar as transações.

lá na wiki da embacadero tem todo detalhado o processo já chegaram a ler.?

http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/FireDAC.Transactions_Sample

http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Managing_Transactions_(FireDAC)

 

Bom dia! No meu caso, quando ocorre o problema, são em telas que não faço uso de transações, ou seja, cadastros simples.E Nas telas onde uso transações, procuro fazer da forma que a documentação orienta. De início achei que o problema poderia ser "comigo", mas já vi outros relatos de casos semelhantes, então acho que é algo no FireDAC\Firebird.

Link para o comentário
Compartilhar em outros sites

4 horas atrás, Rafael Mota Facundo disse:

Oi, datilas, blz! Não entendi onde colocou esses comandos, poderia me explicar? Apenas isso resolveu, ou teve que alterar alguma configuração no componente de conexão?

antes de começar qualquer operação que atualize o db (execsql, dataset.edit, insert update etc.. )

 If Not FDConnection1.InTransaction Then
  FDConnection1.StartTransaction;

depois de execsql , post , aplyupdate etc..

 If  FDConnection1.InTransaction Then
  FDConnection1.Commit;

 

Link para o comentário
Compartilhar em outros sites

  • 1 mês depois ...

A questão que eu achei foi relacionada ao TXOptions. Usando o Zeos por exemplo, não me preocupava com isso, mas com o Firedac tive que ficar mais atento. O Firedac por padrão abre uma transação para consultar os dados e fecha automaticamente se o autostop estiver true.

Então pra não ter confusão de transações pendentes, deixo o autostart, autostop e autocommit (no TXOptions) sempre em true, e só na hora da transação em si é que mudo na hora o autocommit pra false,  e como o autostart estará true, não preciso explicitar o starttransaction (se não ficará um pendente), faça o que tem que ser feito, e depois dou commit ou rollback, e por fim volto o autocommit pra true.

Não tive mais problemas.

Link para o comentário
Compartilhar em outros sites

  • 2 meses depois ...
Em 09/06/2018 at 09:58, OldProgramer disse:

A questão que eu achei foi relacionada ao TXOptions. Usando o Zeos por exemplo, não me preocupava com isso, mas com o Firedac tive que ficar mais atento. O Firedac por padrão abre uma transação para consultar os dados e fecha automaticamente se o autostop estiver true.

Então pra não ter confusão de transações pendentes, deixo o autostart, autostop e autocommit (no TXOptions) sempre em true, e só na hora da transação em si é que mudo na hora o autocommit pra false,  e como o autostart estará true, não preciso explicitar o starttransaction (se não ficará um pendente), faça o que tem que ser feito, e depois dou commit ou rollback, e por fim volto o autocommit pra true.

Não tive mais problemas.

Pelo que eu entendi, se no TXTOptions estiver AutoStart = true, não precisarei do FDConnection1.StartTransaction é isso?

 FDConnection.TxOptions.AutoCommit := False;

   try
     //Aqui não precisa iniciar transação???
     gravarVenda;
     gerarRecebimento;
     FDConnection1.Commit;
     FDConnection.TxOptions.AutoCommit := True;
   except
     FDConnection.Rollback;
   end;

Então não seria melhor fazer o contrário? AutoStart = false e só abrir transação quando realmente eu quiser?

Link para o comentário
Compartilhar em outros sites

Muito ruim Firedac.... tinha que ser igual BDE

Deu append, colocou os dados e deu Post no table tem que salvar e dar commit...
No Firedac (com Firebird), se não por esse "monte" de comandos... pode ligar o que for que não vai para na base em tempo real... já me estressei, nem migrei outros projetos.

Ainda migrei um projeto achando que ia ficar mais rápido, com o monte de opção que tem no FetchOptions, ainda ficou mais lerdo. E não foi falta de conhecimento, eu mexi na ferramenta de cima em baixo.. muito ruim.

Link para o comentário
Compartilhar em outros sites

Em 22/08/2018 at 11:33, Rafael Mota Facundo disse:

Pelo que eu entendi, se no TXTOptions estiver AutoStart = true, não precisarei do FDConnection1.StartTransaction é isso?


 FDConnection.TxOptions.AutoCommit := False;

   try
     //Aqui não precisa iniciar transação???
     gravarVenda;
     gerarRecebimento;
     FDConnection1.Commit;
     FDConnection.TxOptions.AutoCommit := True;
   except
     FDConnection.Rollback;
   end;

Então não seria melhor fazer o contrário? AutoStart = false e só abrir transação quando realmente eu quiser?

Exato, qdo uso transações prefiro controlar manualmente pra não ter confusão. Deixo no TXOption tudo on para operações "normais" digamos, mas qdo quero usar transações coloco autocommit em false e não preciso usar start transaction pois ele fará automaticamente.

Link para o comentário
Compartilhar em outros sites

Tive problemas com o  FireDac no Tokyo relacionados com as Transações  linkadas ao FDConnection. Antes, quando

você usava estas transações, bastava setar AutoCommit, AutoStart e AutoStop para true em TxOptions que

ao dar um "DataSet.Post;" a informação era "commitada" no banco. No Tokyo, o AutoCommit para de funcionar

após abrir uma Query que necessita de fetch parcial e só volta quando todos os registros são trazidos, nesse intervalo

nada é "commitado" pelo Connection.Transaction .

O Resultado disso são inúmeros dead locks e informações que só são salvas no fechamento do sistema.

Eu resolvi isso setando um FDTransaction em Connection.UpdateTransaction para controlar os updates e inserts,

deixando as consultas / fetchs para a  Connection.Transaction.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 1 mês depois ...

Denis estou com esse problema no firedac no tokio

nada é "commitado" pelo Connection.Transaction .

O Resultado disso são inúmeros dead locks e informações que só são salvas no fechamento do sistema.

Eu resolvi isso setando um FDTransaction em Connection.UpdateTransaction para controlar os updates e inserts,

deixando as consultas / fetchs para a  Connection.Transaction.

 

ME EXPLICA DIREITINHO COMO VC FEZ ISSO

Em 04/09/2018 at 16:32, Denis Denon disse:

Tive problemas com o  FireDac no Tokyo relacionados com as Transações  linkadas ao FDConnection. Antes, quando

você usava estas transações, bastava setar AutoCommit, AutoStart e AutoStop para true em TxOptions que

ao dar um "DataSet.Post;" a informação era "commitada" no banco. No Tokyo, o AutoCommit para de funcionar

após abrir uma Query que necessita de fetch parcial e só volta quando todos os registros são trazidos, nesse intervalo

nada é "commitado" pelo Connection.Transaction .

O Resultado disso são inúmeros dead locks e informações que só são salvas no fechamento do sistema.

Eu resolvi isso setando um FDTransaction em Connection.UpdateTransaction para controlar os updates e inserts,

deixando as consultas / fetchs para a  Connection.Transaction.

NAO ENTENDI MAS ESTOU PASSANDO POR ESSE PROBLEMA TEM COMO ME EXPLICAR DIREITO

Link para o comentário
Compartilhar em outros sites

  • Moderadores

6.3 - Mostre respeito pelo modo de escrever. Escreva de modo claro, gramaticalmente e semanticamente correto. Não escreva TUDO EM MAIÚSCULAS. Isso é lido como se estivesse gritando e é considerado rude. Favor leia as regras do fórum.

  • Curtir 1
Consultor SAC ACBr Juliomar Marchetti
 

Projeto ACBr

skype: juliomar
telegram: juliomar
e-mail: [email protected]
http://www.juliomarmarchetti.com.br
MVP_NewLogo_100x100_Black-02.png
 

 

Link para o comentário
Compartilhar em outros sites

Tive problemas com o  FireDac no Tokyo relacionados com as Transações  linkadas ao FDConnection. As informações simplemente ficavam em cache, apesar de não estar usando cache de update. essas informações so seriam comitadas se fechar a aplicação, depois de umas pesquisas e de alguns teste no meu caso e acredito que todos se resolve na seguinte maneira, no meu caso ficou resolvido nos teste:

 

Em UpdateOptions, marque a opção de autocommitupdate para True, e refreshmode para rmAll;

Já fiz vários testes e simulei varias quedas de energia, mesmo os dados persistiram no banco.

Espero que funcionem com vocês.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 4 semanas depois ...

Bom dia.

Em 28/08/2018 at 11:34, OldProgramer disse:

Exato, qdo uso transações prefiro controlar manualmente pra não ter confusão. Deixo no TXOption tudo on para operações "normais" digamos, mas qdo quero usar transações coloco autocommit em false e não preciso usar start transaction pois ele fará automaticamente.

Para contribuir com a postagem, segundo a documentação disponível em http://docwiki.embarcadero.com/Libraries/Tokyo/en/FireDAC.Stan.Option.TFDTxOptions.AutoCommit, não há a necessidade de setar a flag AutoCommit ao startar uma transação.

Citar

If the application called the StartTransaction method, then the automatic transaction management will be disabled until the corresponding Commit or Rollback method call. Generally, there is no need to set the AutoCommit property value to False, just use the explicit transaction control (StartTransaction, Commit, or Rollback) when you need it. 

 

Para contribuir com a discussão, enfrentei o mesmo problema. Depurando, identifiquei que a Flag AutoCommit só tem efeito sobre as instruções aplicadas através de "ExecSQL"; ao dar um "Post" em um FDTable a flag não dá commit no banco, deixando isto para quando a conexão for encerrada(dará o commit pois está definido nas configurações da conexão - TxOptions.DisconnectAction). Contornei isto, dando um "CommitRetaining" a cada "Post" da FDTable. Como estou migrando do BDE para FireDac, criei uma "casca" que foi aonde pude aplicar esta ideia a todos os "Posts" dados pelo sistema.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Moderadores
Em 03/05/2018 at 10:10, Juliomar Marchetti disse:

Bom dia

acho que a primeira coisa é entender como funciona e quando usar as transações.

lá na wiki da embacadero tem todo detalhado o processo já chegaram a ler.?

http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/FireDAC.Transactions_Sample

http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Managing_Transactions_(FireDAC)

 

Desses links já chegaram a ler essa parte

image.png

1 hora atrás, jeronimoza disse:

Bom dia.

Para contribuir com a postagem, segundo a documentação disponível em http://docwiki.embarcadero.com/Libraries/Tokyo/en/FireDAC.Stan.Option.TFDTxOptions.AutoCommit, não há a necessidade de setar a flag AutoCommit ao startar uma transação.

 

Para contribuir com a discussão, enfrentei o mesmo problema. Depurando, identifiquei que a Flag AutoCommit só tem efeito sobre as instruções aplicadas através de "ExecSQL"; ao dar um "Post" em um FDTable a flag não dá commit no banco, deixando isto para quando a conexão for encerrada(dará o commit pois está definido nas configurações da conexão - TxOptions.DisconnectAction). Contornei isto, dando um "CommitRetaining" a cada "Post" da FDTable. Como estou migrando do BDE para FireDac, criei uma "casca" que foi aonde pude aplicar esta ideia a todos os "Posts" dados pelo sistema.

 

  • Curtir 1
Consultor SAC ACBr Juliomar Marchetti
 

Projeto ACBr

skype: juliomar
telegram: juliomar
e-mail: [email protected]
http://www.juliomarmarchetti.com.br
MVP_NewLogo_100x100_Black-02.png
 

 

Link para o comentário
Compartilhar em outros sites

22 minutos atrás, Juliomar Marchetti disse:

Desses links já chegaram a ler essa parte

image.png

 

Sim, já havia olhado a referida documentação. Como dito ali, este seria o melhor caminho... porém, não é viável aplicar este conceito a minha necessidade. Estou migrando do BDE para FireDac(7 para Tokyo), e isto implicaria em, primeiramente, setar o "Connection" de todos os componentes de acesso a dados para conseguir centralizar este controle. No momento, estou trabalhando com com a conexão definida ao "ConnectionName".

Entendo que o grande ponto no meu contexto é: o FireDac abre uma transação implícita ao dar um ".Post" que, se não for comitada, só será no momento no encerramento da conexão.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 3 meses depois ...

Contribuindo um pouco mais com esta discussão...

Enfrentei algumas outras "inconsistências"(inconformidades do meu projeto) com as "auto" transações do FireDAC. Foi necessário alterar o valor default da propriedade "TxOptions.StopOptions", ficando "[xoIfAutoStarted, xoFinishRetaining]". Dentre algumas inconformidades, surgiram alguns "deadlocks", transações que ficavam abertas devido a muitas tabelas estarem abertas em tempo de desenvolvimento.

Leitura que contribuiu para elucidação:

https://stackoverflow.com/questions/36696159/firedac-applyupdates-and-transaction-control

Link para o comentário
Compartilhar em outros sites

  • Consultores

Já usei muitas vezes transações "AutoStarted" por questão de simplicidade. Mas sinceramente recomendo não utilizar. Quando você não controla o fluxo das transações é muito comum acontecerem vários erros.

  • Curtir 1

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

  • 3 meses depois ...

Bom, sei que o tópico é antigo,  mas com comentários após 2 anos, presumo que, como eu, muitos irão passar por aqui, lendo sobre erros com transactions.

Não vou postar dúvida, mas, um detalhe importante diante das soluções apresentadas acima (tentar comitar, e se não der, dar um rolback), que até agora testei no Delphi 10.1, Firebird 2.5 e usando Firedac. Coloquei o FDConnection, uma FDQuery, um Datasource. Deixei o FDQuery setado Como padrão, ou seja FetchOptions.RowSetSize 50, e FetchOptions.Mode = fmOnDemand. e Claro, um DBGrid.

Criei uma tabela TAB_TESTE, criei um campo TESTE (varchar 50). Inseri 100 cadastros. No sql da FDQuery, "Select * from tab_teste". Ok, agora vem: ao dar um FDQuery1.active := true, claro, ele irá abrir, trazendo 50 cadastros,  e ai vem: deixa a transação aberta (e só fecha ela quando chegar no final da tabela), por exemplo, avançando até o final do DBGrid.

Bom, se logo após o FDQuery1.active = true, eu mandar dar um commit ou rolback na transação, ao tentar rolar o dbgrid até o final.... claro, não vai carregar nenhum cadastro após o 50º.

E é daqui para frente que estou desde sábado último tentando entender porquê "as vezes", o master/detail não salva.

Bem, o código?

...Se não tiver uma transação ativa, iniciar, se já tiver (e tinha) não iniciar, ou pior, comitar, ou dar rolback. Bom, daqui para a frente ví cada erro: parâmetro ftInteger, quando chamados ".AsString", disparando erro. Mas o errão que me fez perder tempo (delphi 10.1 berlim), ao tentar salvar um master/detail (venda e itens da venda), onde há parâmetros nos sql da FDQuery (com a transação lá, aberta, na tabela de fornecedores):

 

"Firedac -402. operation cannot be performed without assigned selectcommand"

Ainda não testei com zeus, cds, etc.

Bom, colocar FetchOptions.Mode = fmAll "resolve" isto, mas claro, poderá complicar, se houverem muitos cadastros. Iniciar a transação, abrir a tabela e comitar a transação, bom, e o cadastro 51 em diante...

Link para o comentário
Compartilhar em outros sites

  • Este tópico foi criado há 1739 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Visitante
Este tópico está agora fechado para novas respostas
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.