Beforepost recording wrong information

Asked

Viewed 68 times

1

In my Delphi application, when breaking an agreement with my Client I must update the operations data!

So I start by deleting some customer data, the problem happens right there:

procedure TDMClientes.QOperacoesBeforePost(DataSet: TDataSet);
begin
  QuebrarAcordo(DMClientes.QOperacoesBanco.AsInteger,
                DMClientes.QOperacoesCLIENTE.AsInteger,
                DMClientes.QOperacoesNROPERACAO.AsString,
                DMClientes.QOperacoesREMESSA.AsInteger,
                V_CodEvento_Quebra,true);
end;

In the code above I call a function QuebrarAcordo that is in another unit, there works properly:

ExecSql('UPDATE OPERACOES SET VALOR_DIVIDA = VALOR_ORIGINAL WHERE CLIENTE = XXXXXX');

Sql runs correctly and returns to finish the BeforePost, but there’s a Roolback in the database!

What may be causing this roolback without warning of an error?

  • 1

    that DataSet is a third party component or is native if third party check if you own the property AutoCommit, and inform as she this!

  • It does, but this fake.

1 answer

1


The problem is that there is a Roolback, let’s go in pieces...

You initiated a transaction with the bank that called the BeforePost of the component, then the DataSet this in Editing mode, ai you called a function that performs an Update directly in the Database.

So far so good, but when you return and complete the Beforepost guess? The BeforePost will make a post (ie a commit) in your Database recording everything that the component would already record!

So, inside the BeforePost, before calling the function, you must Cancel the Dataset Edit status. Try to leave your procedure this way:

procedure TDMClientes.QOperacoesBeforePost(DataSet: TDataSet);
begin
  DMClientes.QOperacoesBanco.Cancel; //Cancela a edição que chamou o BeforePost
  QuebrarAcordo(DMClientes.QOperacoesBanco.AsInteger,
                DMClientes.QOperacoesCLIENTE.AsInteger,
                DMClientes.QOperacoesNROPERACAO.AsString,
                DMClientes.QOperacoesREMESSA.AsInteger,
                V_CodEvento_Quebra,true);
    DMClientes.QOperacoes.Refresh; //Atualiza o Componente, pois, ouve alterações
    DMClientes.QOperacoes.Edit; //Coloca novamente em Edição para finalizar outras alterações
end;

But... the ideal would be instead of calling an external function to BeforePost you run Update right there:

procedure TDMClientes.QOperacoesBeforePost(DataSet: TDataSet);
begin
  ExecSql('UPDATE OPERACOES SET VALOR_DIVIDA = VALOR_ORIGINAL WHERE CLIENTE = XXXXXX');
end;

Of course, if there is no need to call the function!

Edit:

Another more decent way to do (theoretically more correct) would be to pass a Boolean variable true (validating that it must perform the external function), and AfterPost check the variable and run the Function call, leaving the BeforePost Clean of additional codes Cancel, Refresh and Edit.

Explaining, when the procedure arrives in the AfterPost, means that the component has already left editing mode and is already with the updated information, no longer needing additional command! Then, it would be enough to validate if the variable is in True and execute the external function call!

  • I cannot run direct, because there are other validations within the BeforePost, but your solution works perfectly.

  • @Gabrielrodrigues, now at home at home I ended up giving a review, please analyzes and confirms if fits better this approach!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.