Jump to content

dev botao

Controle de Concorrencia no Firebird


carlosinfoteen
  • Este tópico foi criado há 2498 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Pessoal bom dia,

Estou com um pequeno problema em um sistema que usa DBExpres e Firebird.

O problema é com justamente o controle de concorrência,

Ou seja, eu crio um pedido de vendas e já gravo o cabeçalho carregando o valor do ultimo generator
criado para aquele tabela (ID_PEDIDO), para poder mostrar o numero do pedido para aquele usuario e tambem poder gravar no (id_detalhe) da tabela de itens do pedido.

O problema é que se 3, 4 usuários criarem um pedido ao mesmo tempo carrega o generativo um do outro e os itens sao gravados em pedido errado.


QUAL A MELHOR FORMA DE CONTROLAR ISSO  com dbexpress e firebird?

Link to comment
Share on other sites

  • Moderadores
36 minutos atrás, carlosinfoteen disse:

O problema é que se 3, 4 usuários criarem um pedido ao mesmo tempo carrega o generativo um do outro e os itens sao gravados em pedido errado.

Quando você obtêm o generator deve instruir a incrementar o valor.

select gen_id(NOME_DO_GENERATOR, 1) from RDB$DATABASE

O segundo parâmetro já incrementa o valor do generator, assim nunca vai haver duplicidade.

 

Equipe ACBr BigWings
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

 

 

Link to comment
Share on other sites

5 minutos atrás, BigWings disse:

Quando você obtêm o generator deve instruir a incrementar o valor.


select gen_id(NOME_DO_GENERATOR, 1) from RDB$DATABASE

O segundo parâmetro já incrementa o valor do generator, assim nunca vai haver duplicidade.

 

Obrigado BigWings,

Bem tem uma triger na tabela CabecaolhoPedido que ja dispara o incremento do ID desta tabela. Dai uso select gen_id(NOME_DO_GENERATOR, 0) from RDB$DATABASE , pra não incrementar mais e trazer o recem gerado. Aqui é que está o problema. Pois se vários clicar em centésimos de sengudo pega o ultimo generator. E é este que jogo para o Id_detalhes_pedido, ou seja tabala dos itens do pedido, dai o conflito.

E outra, é que estou controlando o numero do pedido com o ID também. acho que vou criar outro campo NumeroPedido

Dai para trazer o ID ja incrementado como você sugeriu.

 

Link to comment
Share on other sites

17 minutos atrás, carlosinfoteen disse:

E outra, é que estou controlando o numero do pedido com o ID também. acho que vou criar outro campo NumeroPedido

Eu criei uma função para isso.

        tb.Close;
        tb.SQL.Clear;
        tb.SQL.ADD('SELECT COALESCE(GEN_ID(' + sGene + ',' + IntToStr (Incremento) + '),0) AS CODIGO FROM RDB$DATABASE');
        tb.Prepare;
        tb.Open;
        if tb.FieldByname('CODIGO').AsInteger = 0 then
            result := 1
        Else
            result := tb.FieldByname('CODIGO').AsInteger;
        tb.Close;

Nunca tive problemas com concorrência de usuários.

uso nCodigodoPeidido := MAX_GENERATOR( 'NOME_GENERATOR',1) se quero incrementar, se quero pegar apenas o último,

 nCodigodoPeidido := MAX_GENERATOR( 'NOME_GENERATOR',0)

_____________

Prates, Agnaldo

Link to comment
Share on other sites

  • Moderadores

Segue outras ideias 

procedure TDm.AtribuiId(Genname, Campo: String; DataSet: TDataSet);
begin
  if dataset.State in [Dsinsert] then
    Dataset.FieldByName(Campo).AsInteger := ProximoId(Genname);
end;


function TDm.ProximoId(Genname: String): Integer;
Var
  Resultset : TcustomSqlDataset;
  Sqlstmt   : String;
begin
  SqlStmt   := 'select gen_id('+Genname+',1)as Id From RDB$DATABASE;';
  Resultset := nil ;
  result    := 0;
  Try
    SQLConnection1.Execute(SqlStmt,nil,@Resultset);
    if Assigned(Resultset) then
    begin
      result := Resultset.fieldbyname('id').AsInteger;
    end;
  Finally
    Resultset.Free;
  end;
end;

usando 

procedure TDm.tbAtividadeBeforePost(DataSet: TDataSet);
begin
  AtribuiId('GEN_ATIVIDADE_ID', 'ICODIGOATIVIDADE', DataSet);
end;

procedure TDm.tbAreaBeforePost(DataSet: TDataSet);
begin
 AtribuiId('GEN_AREA_ID', 'IAREADEATUACAO', DataSet);
end;

procedure TDm.tbPrepostoBeforePost(DataSet: TDataSet);
begin
  AtribuiId('GEN_PREPOSTO_ID', 'ICODIGOPREPOSTO', DataSet);
end;

 

Equipe ACBr Henrique Leonardo
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Tecnólogo em processamento de dados

E-mail [email protected] - Skype : hleorj

Link to comment
Share on other sites

  • Este tópico foi criado há 2498 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.