Ir para conteúdo
  • Cadastre-se

dev botao

Múltiplas transações


Recommended Posts

  • Membros Pro

Bom dia!

Não estou conseguindo trabalhar com varias transações. 

Nosso sistema trabalha com empresa cadastro, ou seja, posso ter varios bancos(empresa), mas todo cadastro é realizado em apenas uma que persiste as informações nos outro banco. Ex: cadastro um produto na empresa 1 e replica para empresa 2, 3 etc...

Só que se por algum motivo falhar a inserção das informações na empresa3, por exemplo, preciso abortar o cancelamento no outros banco tbm.

Uso firedac com firebird. Tentei assim:

transacao = TFDTrasaction e ADCEmpresa =  TFDConnection

 

ADCEmpresa.Transaction:= transacao;
      transacao.StartTransaction;
      vEmpAtual := FrPrincipal.vAliasEmp;
      While Not DmPrincipal.QrEmpCad.Eof Do
      Begin
        Try
          If FrPrincipal.CodigoEmpresaCad > 0 Then
            ConfiguraEmpresa(RetornaAlias(DmPrincipal.QrEmpCadCODIGOEMPRESA.Value));  // aqui eu crio uma nova conexão em outro banco

          if FrPrincipal.CodigoEmpresaCad > 0 then
            Gravar(Trunc(DMPrincipal.QrEmpCadCODIGOEMPRESA.Value))
          else
            Gravar(FrPrincipal.CodigoEmpresa);

          If FrPrincipal.CodigoEmpresaCad <= 0 Then
             exit;
        Except

          transacao.Rollback;
          Application.MessageBox(Pchar('Não foi possível gravar Registro na empresa ' + FormatFloat('000',DmPrincipal.QrEmpCadCODIGOEMPRESA.Value)),'Atenção',MB_ICONEXCLAMATION);
          exit;
        End;
        DmPrincipal.QrEmpCad.Next;
      End;
      transacao.Commit;

Mas da erro no rollback, com o erro  mais ou menos assim connection must is active

Como faria isso?

Link para o comentário
Compartilhar em outros sites

  • Moderadores

Bom dia

nesse link tem informações relevantes em tratar Transações para FireBird com FireDAC

https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Managing_Transactions_(FireDAC)

em espefico esse trecho pra frente

image.png

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

  • Membros Pro

Boa tarde, Juliomar!

Mesmo lendo e tentando implementar não obtive sucesso!, gera o mesmo erro .

Connection must  is active

Vc teria um exemplo como ficaria no meu caso? 

Link para o comentário
Compartilhar em outros sites

  • Moderadores
56 minutos atrás, MSOL disse:

Boa tarde, Juliomar!

Mesmo lendo e tentando implementar não obtive sucesso!, gera o mesmo erro .

Connection must  is active

Vc teria um exemplo como ficaria no meu caso? 

o problema é que tu deve ter dois tipos de transações. uma que tu está deixando o componente trabalhar e outra que tu controla

dai tu vai ter problemas pois ele o componente vai tratar ela de fechar e nesse caso ele já deu o commit e fechou a transação por isso do erro

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

  • Membros Pro

Boa tarde, Juliomar!

Eu desabilitei o autocommit do TFDConnection;

vou demostrar como fiz

COnexao = TFDConnection que é criado dentro da classe ConfiguraEmpresa.

While Not DmPrincipal.QrEmpCad.Eof Do
      Begin
        Try
            ConfiguraEmpresa(RetornaAlias(DmPrincipal.QrEmpCadCODIGOEMPRESA.Value));    aqui crio a conexão para cada banco existente
            transacao:= TFDTransaction.Create(nil);

            transacao.Connection:= Conexao;
            FrPrincipal.conexaoteste.UpdateOptions.LockWait := False;
            transacao.Options.ReadOnly := False;
            transacao.Options.Isolation := xiReadCommitted;
            transacao.StartTransaction;
            Gravar; aqui grava os registros suando um TFDQuery apontado para COnexao
        Except
          transacao.Rollback;
          Application.MessageBox(Pchar('Não foi possível gravar Registro na empresa ' + FormatFloat('000',DmPrincipal.QrEmpCadCODIGOEMPRESA.Value)),'Atenção',MB_ICONEXCLAMATION);
          exit;
        End;
        DmPrincipal.QrEmpCad.Next;

      End;
      transacao.Commit;

O que está de errado no codigo?

Link para o comentário
Compartilhar em outros sites

  • Moderadores
Em 22/04/2024 at 17:56, MSOL disse:

Não tem. As ações que estou fazendo está neste exemplo. Em momento alguma faço TFDConnection.StarTransaction;

 

assim qeu possível vou montar um exemplo

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

  • Membros Pro

Boa tarde, Juliomar!

Eu resolvi o problema e vou postar aqui se alguem tiver o mesmo problema;

Como eu precisava gerenciar a transação de bancos distintos(porem mesmo DBMS), a solução foi usar o FDManager(não conhecia como funcionava);

Fiz assim:

 

 

 While Not ....
 Begin 

   try

       conexaoAtual := TFDConnection.Create(nil);
       conexaoAtual.TxOptions.AutoCommit:= false;
        conexaoAtual.TxOptions.DisconnectAction:= xdNone;

       transacao:= TFDTransaction.Create(nil);
       transacao.Options.DisconnectAction:= xdNone;

       transacao.Options.AutoCommit:= false;

      transacao.Connection:= ConexaoAtual;

      TabelaPrincipa:= TFDQuery.Create(nil);

      TabelaPrincipal.Connection:= ConexaoAtual;
      TabelaPrincipal.UpdateTransaction:= transacao;
      TabelaPrincipal.Transaction:= transacao;

      ConexaoAtual.transaction:= transacao;
      transacao.StartTransaction;

//      faz aqui os inserts, updates  etc...     usando  a query TabelaPrincipal

  //    Aqui foi o pulo do gato. Ao inves de usar transacao. commit, chamo os metodos , criei 2 metodos, uma para commitar e outro para da Rollback

   CommitAllTransactions; 

except

  RollbackAllTransactions; 

end    

end

 

procedure CommitAllTransactions;
var
  FDManager: TFDManager;
  i: integer;
begin
  FDManager := TFDManager.Create(nil);
//     Percorrer todas as conexões ativas
    for I := 0 to FDManager.ConnectionCount -1 do
      if FDManager.Connections[i].InTransaction then
         Connections[i].commit;
end;

 

procedure RollbackAllTransactions;
var
  FDManager: TFDManager;
  i: integer;
begin
  FDManager := TFDManager.Create(nil);
//     Percorrer todas as conexões ativas
    for I := 0 to FDManager.ConnectionCount -1 do
      if FDManager.Connections[i].InTransaction then
         Connections[i].Rollback;
end;

 

Espero que possa ser util para alguém

Obrigado Juliomar pela atenção

Link para o comentário
Compartilhar em outros sites

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.

The popup will be closed in 10 segundos...