Ir para conteúdo
  • Cadastre-se

dev botao

Controle de Concorrencia no Firebird


  • Este tópico foi criado há 2373 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros 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 para o comentário
Compartilhar em outros sites

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

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • 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.