sql >> Base de Datos >  >> RDS >> Sqlserver

¿Cómo implementar un mecanismo de bloqueo simple para una aplicación multiusuario?

Una solución simple que implementé en una aplicación....

CREATE TABLE RecordLocks(
[RecordId] [varchar](8) NOT NULL,
[UserName] [varchar](100) NOT NULL,
[datetimestamp] [smalldatetime] NOT NULL,
[PC] [varchar](100) NOT NULL

)
GO

datetimestamp tiene un valor predeterminado de GetDate() RecordId es un VARCHAR debido a la clave principal en la tabla que estoy bloqueando (no es mi elección). También esta tabla tiene los índices obvios

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

Primero elimine y registre más de 2 horas (cambie para adaptarlo)

Verifique que no haya ningún registro que ya bloquee el que desea bloquear y, si no, inserte el candado.

Seleccione el registro con el RecordId que nos interesa.

Luego, en el código de llamada, verifique si el bloqueo ha sido exitoso. Si el nombre de usuario y la PC que regresan de la selección coinciden con los datos que acaban de pasar, el bloqueo fue exitoso. Si el nombre de usuario coincide pero la PC no, el mismo usuario tiene el registro abierto en una máquina diferente. si el nombre de usuario no coincide otro usuario ya lo tiene abierto. Muestro un mensaje al usuario si no tiene éxito, es decir, este registro está actualmente bloqueado por JoeB en la estación de trabajo XYZ.

Cuando el usuario guarda el registro o se aleja, simplemente elimine el bloqueo del registro.

Estoy seguro de que hay otras formas, pero esto funciona bien para mí.

Actualizar

Solo se insertará un registro si no existe. La siguiente selección devolverá un registro. Si el nombre de usuario y/o la computadora son diferentes a los datos que intenta insertar, el registro ya está bloqueado por otro usuario (o el mismo usuario en una máquina diferente). Así que una llamada lo hace todo (por así decirlo). Entonces, si hago una llamada Exec usp_LockRecord(1234, 'JoeB', 'Workstation1') y el registro que obtengo coincide con los datos. Obtuve un bloqueo exitoso en ese registro. Si el nombre de usuario y/o la PC que obtengo son diferentes, el registro ya está bloqueado. Luego, puedo mostrar un mensaje al usuario para informarle que el registro está bloqueado, hacer que los campos sean de solo lectura, deshabilitar los botones de guardar y decirles quién tiene un bloqueo si lo deseo.