Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como implementar um mecanismo de bloqueio simples para aplicativo multiusuário?


Uma solução simples que implementei em um aplicativo....
CREATE TABLE RecordLocks(
[RecordId] [varchar](8) NOT NULL,
[UserName] [varchar](100) NOT NULL,
[datetimestamp] [smalldatetime] NOT NULL,
[PC] [varchar](100) NOT NULL

)
GO

datetimestamp tem um padrão de GetDate() RecordId é um VARCHAR por causa da chave primária na tabela que estou bloqueando (não é minha escolha). Também esta tabela tem os índices óbvios
CREATE PROCEDURE usp_LockRecord @RecordId VARCHAR(8), @UserName VARCHAR(100), @ComputerName VARCHAR(100)
AS
BEGIN
BEGIN TRAN; 
DELETE FROM RecordLocks WHERE DATEDIFF(HOUR, datetimestamp, GETDATE()) > 2; 
IF NOT EXISTS (Select * from RecordLocks WHERE RecordId = @RecordId) 
    INSERT INTO RecordLocks (RecordId, username, PC) VALUES (@RecordId, @UserName, @ComputerName); 

Select * from RecordLocks WHERE RecordId = @RecordId; 
COMMIT TRAN;
END
GO

Primeira exclusão e registros com mais de 2 horas (alterar para se adequar)

Verifique se não há registro já travando o que deseja travar e se não estiver insira a trava.

Selecione o registro com o RecordId em que estamos interessados.

Em seguida, no código de chamada, verifique se o bloqueio foi bem-sucedido. Se o nome de usuário e o PC retornando da seleção corresponderem, os dados que acabaram de passar no bloqueio foram bem-sucedidos. Se o nome de usuário corresponder, mas o PC não corresponder, o mesmo usuário terá o registro aberto em uma máquina diferente. se o nome de usuário não corresponder outro usuário já o tem aberto. Eu mostro uma mensagem para o usuário se seu I.E não for bem-sucedido. Este registro está atualmente bloqueado por JoeB na estação de trabalho XYZ.

Quando o usuário salva o registro ou navega para longe, basta excluir o bloqueio do registro.

Tenho certeza de que existem outras maneiras, mas isso funciona bem para mim.

Atualizar

Um registro só será inserido se não existir. A seleção a seguir retornará um registro. Se o nome de usuário e/ou pc for diferente dos dados que você tenta inserir o registro já está bloqueado por outro usuário (ou mesmo usuário em uma máquina diferente). Assim, uma chamada faz tudo (por assim dizer). Então, se eu fizer uma chamada Exec usp_LockRecord(1234, 'JoeB', 'Workstation1') e o registro que recebo corresponde aos dados que obtive com sucesso um bloqueio nesse registro. Se o nome de usuário e/ou PC que recebo for diferente, o registro já está bloqueado. Eu posso então exibir uma mensagem para o usuário informando que o registro está bloqueado, tornar os campos somente leitura, desabilitar os botões de salvar e dizer a eles quem tem um bloqueio, se eu desejar.