Skip to content

Um exemplo de construção de Tread Safe para comitação dos dados Firedac

License

Notifications You must be signed in to change notification settings

filhotecmail/ThreadTransact

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Uma construção de Isolate Transaction Thread

Objetivo .:

Simular transações com banco de dados Firebird, por meio de transações seguras em Thread enviadas ao processador para que se completem e terminem seu ciclo.

Ex: de uso.

procedure TForm5.Button1Click(Sender: TObject);
begin
ExecuteThread_Manutencaoprodutos(5000);
end;

O MétodoAsync.Await

Configure o Tempo de delay para inicio do procedimento.

Para isso foi criado um método Async, que vai executar a thread.

 Async
   .AWait(procedure
     begin
      with TTransactionData.Create do
      begin
        DatabaseUserName := 'sysdba';
        DatabasePassword := '1234';
        DatabasePort     := 3050;
        Database         := 'c:\meubanco\banco.fdb';
        Host             := '127.0.0.1';
        Start;
      end;
     end,dwMilliseconds);
     

Create da Thread

No on create da Thread iremos construir todos os recursos possíveis para se trabalhar com transações com firedac.

constructor TTransactionData.Create;
begin
 inherited Create(True);
 
 FreeOnTerminate:= True;
 
{$REGION 'Criação dos Componentes de transação, Nao precisa Destruir
  pois a ThreadClass é o Pai de todos , ele quem vai destruir ao terminar a Thread'}

  FCon := TFDConnection.Create( nil );
  FTransact := TFDTransaction.Create( nil );
  FQuery := TFDQuery.Create( nil );
  FPsys := TFDPhysFBDriverLink.Create( nil );
  FLogTransaction := TStringList.Create;

{$ENDREGION}

 {$REGION 'Prepara os componentesde Transação'}
 
  FPsys.ThreadSafe := True;

  FQuery.Connection := FCon;
  FTransact.Connection := FCon;

  FCon.UpdateOptions.LockWait := False;
  Fcon.UpdateOptions.AutoCommitUpdates;
  FCon.LoginPrompt := False;
  FCon.ResourceOptions.AutoConnect   := True;
  FCon.ResourceOptions.AutoReconnect := True;
  
  FTransact.Options.AutoCommit := True;
  FTransact.Options.ReadOnly := False;
  FTransact.Options.Isolation := xiReadCommitted;
  
 {$ENDREGION}

  {$REGION 'Assinatura dos Eventos do conector'}

   with FCon do
   begin
   
    AfterCommit     := oConAfterCommit;
    AfterConnect    := oConAfterConnect;
    AfterDisconnect := oConAfterDisconnect;
    AfterRollback   := oConAfterRollback;
    AfterStartTransaction  := oConAfterStartTransaction;
    BeforeCommit           := oConBeforeCommit;
    BeforeConnect          := oConBeforeConnect;
    BeforeDisconnect       := oConBeforeDisconnect;
    BeforeRollback         := oConBeforeRollback;
    BeforeStartTransaction := oConBeforeStartTransaction;
    onError                := oConError;
    onLogin                := oConLogin;
    onLost                 := oConLost;
    onRecover              := oConRecover;
    onRestored             := oConRestored;
    
   end;

  {$ENDREGION}

 OnTerminate := DoOnTerminate;
 

end;

##Como trabalhar. Você vai trabalhar dentro do método DoTransactStatements, criando sua logica;

function TTransactionData.DoTransactStatements: TTransactionData;
var
 I: Integer;
begin
Result := Self;

 FTransactionStr := 'SELECT * FROM CADCLIENTES C WHERE CHAR_LENGTH(TRIM(C.USUARIO)) <= 0';
 FTransactValues := ['ADMINISTRADOR'];

if FCon.Connected then
   FCon.CloneConnection;
   
FTransact.StartTransaction;

Assert( not FTransactionStr.Trim.IsEmpty , 'Não existe um SQL Montando de Update ou Insert !');
Assert( Length(FTransactValues) > 0 , 'Você nao alimentou os parametros de valores');

   
   
try 

 FQuery.Open(FTransactionStr);
 
finally

 if (( FQuery.IsEmpty ) or ( FQuery.RecordCount <= 0 ) ) then
  begin
   WriteLog('Nao existem dados a serem atualizados!');
   raise Exception.Create('Nao existem dados a serem atualizados!');
  end;
    
end;

 FQuery.First;
 FQuery.DisableControls;
 
while not FQuery.Eof do
begin  

 FQuery.Edit;
 
 FQuery.FieldValues['USUARIO'] := FTransactValues[0];
 
 FQuery.Post;
 
 FQuery.Next;   
 
end;

{$REGION 'Nao remova essas linhas'}

 FCon.CloneConnection;       
 TrimAppMemorySize;
 
{$ENDREGION}
 
 
end;

Dentro do método Execute você pode verificar como está sendo executado e fazer todas as validações possíveis que deseja

procedure TTransactionData.Execute;
begin
 inherited;

  While True do
   begin
   
    Sleep(100);  

    if FLogFilePatch.Trim.IsEmpty then
       FLogFilePatch:= ExtractFilePath(ParamStr(0));

    if FLogFilename.Trim.IsEmpty then
       FLogFilename := 'Threadlog.txt';   
   try 
   
    ValidaDadosBancodeDados
      .MontaConexao
       .DoTransactStatements; 
       
   except
   
    on E: Exception do
    begin
       WriteLog(E);
       Abort;
    end;
    
   end;
       
  end;
  
end;

##Exemplo de Log

Se você não preencher as propriedades de LogPatch e LogFileName , o sistema automaticamente irá criar o arquivo de log na pasta da aplicação. image

About

Um exemplo de construção de Tread Safe para comitação dos dados Firedac

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages