Ir para conteúdo
Fórum Script Brasil
  • 0

Como controlar o acesso simultaneo em um tabela para que 2 usuários nã


cassios

Pergunta

Boa tarde galera não to sabendo como fazer, tenho um sistema que será utilizado em rede, porém nos testes que fiz se 2 usuários acessarem a mesma tabela no mesmo tempo para inserir um código no ou alterção da um erro.

O erro é o seguinte vai gravar para os dois usuário com o mesmo código que apareceu para eles quando começaram a incluir porem acontece que depois que um usuário acabou de incluir o registro tudo beleza mas o outro usuário que demorou um poco a mais para cadastrar vai gravar com o mesmo código mas com as informações que o segundo usuário colocou.

Bem preciso de algo que quando um usuário começa o processo de inclusão, o sistema não permita que um outro usuário da rede acesse o mesmo registro, ou que deixe acessar mas que jogue o código para frente.

Ex: um usuario dei inicio ao cadastramento e seu código é o 1, se o outro usuario da rede querer incluir um registro tambem o sistema trave o acesso para ele com uma menssagem dizendo que já esta em uso ou no caso que trate e jogue o código para frente no caso seria 2 e ambos os usuários conseguissem concluir seus trabalhos.

Desde já agradeço, e me indiquem a melhor forma de fazer o processo se possívem com exemplos de códigos.

To usando o paradox um componente query e um datasource ligado ao query se precisar mudar me indiquem.

Vlw galera.

Link para o comentário
Compartilhar em outros sites

2 respostass a esta questão

Posts Recomendados

  • 0
Ex: um usuario dei inicio ao cadastramento e seu código é o 1, se o outro usuario da rede querer incluir um registro tambem o sistema trave o acesso para ele com uma menssagem dizendo que já esta em uso ou no caso que trate e jogue o código para frente no caso seria 2 e ambos os usuários conseguissem concluir seus trabalhos.

Uma solução seria usar campo autoincremento, para não causar erros na inclusão.

outras soluções

Quando você programar visando uma rede e quiser bloquear um arquivo, é só chamar o metodo "Edit" da Tabela que estiver usando.

Exemplo:

Table1.edit; 
//Se o registro já estiver bloqueado, ocorrerá um erro, então você deve fazer o seguinte : 

try { para verificar o erro } 
   Table1.edit; 
exception on TDBEngineError do { o erro..} 
   MensageDlg('Registro já esta sendo usado...!',mtInformation,[ mbOk ],0 ); 
end; 

//não use o DBNavigation
//Bloqueia uma Tabela paradox 


procedure LockPDOXTable(TableName,Password : String);
// Requer a DBIProcs na clausula uses da unit
var
   TblDesc: CRTblDesc;
   LocDB : TDatabase;
begin
   Check(DBIInit(nil));
   Randomize;
   LocDB := TDatabase.Create(nil);
   with LocDB do begin
   Params.Add('path=' + ExtractFilePath(TableName));
   DatabaseName := 'PDOXEncryptDB' + IntToStr(Random(50));
   DriverName := 'STANDARD';
   Connected := True;

   FillChar(TblDesc, SizeOf(CRTblDesc), 0);
   StrPCopy(TblDesc.szTblName, ExtractFileName(TableName));
   with TblDesc do begin
       bProtected := True;
      StrPCopy(TblDesc.szPassword, Password);
   end;
   try
     Check(DbiDoRestructure(LocDB.Handle, 1, @TblDesc,nil, nil, nil, False));
   finally
     LocDB.Free;
     DBIExit;
   end;
end;
outra função
function IsRecordLocked(Table: TTable; ByAnyone: Boolean): Boolean;
//
// Testa se o registro da tabela está travado ou não
//
//  Requer a DBIprocs declarada na clausula uses da unit
//
var
Locked: BOOL;
hCur: hDBICur;
rslt: DBIResult;
begin
Table.UpdateCursorPos;
Check(DbiIsRecordLocked(Table.Handle, Locked));
Result := Locked;
if (not Result) and (ByAnyone) then
    begin
    Check(DbiCloneCursor(Table.Handle, False, False, hCur));
    try
      rslt := DbiGetRecord(hCur, dbiWRITELOCK, nil, nil);
      if (rslt <> DBIERR_NONE) then
         begin
         if (HiByte(rslt) = ERRCAT_LOCKCONFLICT) then
            begin
            Result := True;
            end
         else
            begin
            Check(rslt);
            end;
         end
      else
         begin
         Check(DbiRelRecordLock(hCur, False));
         end;
    finally
      Check(DbiCloseCursor(hCur));
    end;
Function LockTable(Tb: TTable; Vezes: Integer): Boolean;
//
// Testa se a tabela esta bloqueada ou não
//
// Requer DBIprocs, DB, DBTables]
// declarados na clausula Uses da unit
//
var
FlagLock  : Boolean;
Abandonou : Boolean;
Sempre    : Boolean;
Ind       : Integer;
Quant     : Integer;
Temp      : String;
NomeArq   : String;
Mensagem  : String;
begin
Sempre    := (Vezes = 0);
FlagLock  := True;
Abandonou := False;
Quant     := 0;
NomeArq   := '';
Temp      := Tb.TableName;
Ind       := 1;
while Ind <= Length(Temp) do
      begin
      if Copy(Temp,Ind,1) = '.' then
         begin
         Ind := Length(Temp);
         end
       else
         begin
         NomeArq := NomeArq + Copy(Temp,Ind,1);
         end;
       Ind := Ind + 1;
      end;
NomeArq  := UpperCase(NomeArq);
Mensagem := 'O arquivo "'+NomeArq+'" está sendo usado por outro usuário da rede.'+#13;
Mensagem := Mensagem + 'Deseja continuar tentando acessar este arquivo ?';
while FlagLock do
      begin
      try
        Tb.LockTable(ltWriteLock);
        FlagLock := False;
      except
        if (Quant > Vezes) and not Sempre then
            begin
            if MessageBox(GetActiveWindow, Pchar(Mensagem),'Confirmação', MB_ICONQUESTION+MB_YESNO+MB_HELP) = idYes then
               begin
               Quant := 0;
               end
            else
               begin
               FlagLock  := False;
               Abandonou := True;
               end;
            end;
       end;
      Quant := Quant + 1;
      end;
Result := not Abandonou;
end;
function RLock(oTable : TTable): Boolean;
//
// Testa se o registro está travado ou não
//
begin
result := false;
try
  oTable.Edit;
except
  on E:EDBEngineError do
     begin
     if E.Errors[0].ErrorCode = 10241 then
        begin
        Result := True;
        end;
     end;
end;
end;
Procedure TableUnlock(Tb: TTable);
//
// Desbloqueia uma tabela
//
// Requer DBIprocs, DB, DBTables
// declarados na clausula uses da unit
//
Var
i, ilocks: word;
begin
dbiIsTableLocked( Tb.Handle, dbiWRITELOCK, iLocks );
For i :=1 to ilocks do       // Remove todos os locks
    begin
    Tb.UnlockTable(ltWriteLock);
    end
end;

agora é so usar a imaginação

abraço

Link para o comentário
Compartilhar em outros sites

  • 0
tenho um sistema que será utilizado em rede, porém nos testes que fiz se 2 usuários acessarem a mesma tabela no mesmo tempo para inserir um código no ou alterção da um erro.

O erro é o seguinte vai gravar para os dois usuário com o mesmo código que apareceu para eles quando começaram a incluir porem acontece que depois que um usuário acabou de incluir o registro tudo beleza mas o outro usuário que demorou um poco a mais para cadastrar vai gravar com o mesmo código mas com as informações que o segundo usuário colocou.

Bem preciso de algo que quando um usuário começa o processo de inclusão, o sistema não permita que um outro usuário da rede acesse o mesmo registro, ou que deixe acessar mas que jogue o código para frente.

Penso que não é uma boa idéia (impedir que outro usuário faça um cadastro).

O que deve ocorrer é uma mudança de paradigma - tente deixar de lado os conceitos da programação mono-usuário.

Neste contexto, o que deve ser observado é que o tal número que você retorna ao usuário, só deve (pode) ser retornado ao mesmo após a gravação da informação - não ao iniciar. Assim, você deve, ou seguir a sugestão que o Jhonas deu e definir o campo como auto-increment, ou então, obter este novo número (coisa que aparentemente você já faz) no último momento em que você for gravar a informação - como é o caso do efento BeforePost do dataset.

Locar tabelas, não é muito conveniente, visto que você deixará outros usuários impedidos de acessá-la - isto pode deixa-los bastante irritados. :D

No máximo, o lock de registros durante a alteração (não a inclusão), o que é normalmente previsto pelos gerenciadores, ou devem ser setados explicitamente.

Abraços

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...