Una soluzione semplice che ho implementato in un'applicazione ....
CREATE TABLE RecordLocks(
[RecordId] [varchar](8) NOT NULL,
[UserName] [varchar](100) NOT NULL,
[datetimestamp] [smalldatetime] NOT NULL,
[PC] [varchar](100) NOT NULL
)
GO
datetimestamp
ha un valore predefinito di GetDate()
RecordId
è un VARCHAR
a causa della chiave primaria nella tabella sto bloccando (non una mia scelta). Anche questa tabella ha gli indici ovvi
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
Prima elimina e registra più vecchi di 2 ore (cambia per adattarsi)
Controlla che non ci siano record già bloccando quello da bloccare e in caso contrario inserisci il blocco.
Seleziona il record con il RecordId che ci interessa.
Quindi nel codice di chiamata controlla per vedere se il blocco ha avuto successo. Se il nome utente e il PC di ritorno dalla selezione corrispondono, i dati appena passati nel blocco hanno avuto esito positivo. Se il nome utente corrisponde ma il PC non è lo stesso utente ha il record aperto su una macchina diversa. se il nome utente non corrisponde a un altro utente lo ha già aperto. Visualizzo un messaggio all'utente se IE non riuscito Questo record è attualmente bloccato da JoeB sulla workstation XYZ.
Quando l'utente salva il record o si allontana, elimina semplicemente il blocco del record.
Sono sicuro che ci sono altri modi, ma questo funziona bene per me.
Aggiorna
Verrà inserito un record solo se non ne esiste uno. La seguente selezione restituirà un record. Se il nome utente e/o il pc sono diversi dai dati che si tenta di inserire il record è già bloccato da un altro utente (o lo stesso utente su un altro computer). Quindi una chiamata fa tutto (si fa per dire). Quindi, se effettuo una chiamata Exec usp_LockRecord(1234, 'JoeB', 'Workstation1')
e il record che ottengo corrisponde a quei dati che ho ottenuto con successo un blocco su quel record. Se il nome utente e/o il PC che ricevo sono diversi, il record è già bloccato. Posso quindi visualizzare un messaggio per l'utente che informa che il record è bloccato, rendere i campi di sola lettura, disabilitare i pulsanti di salvataggio e dire loro chi ha un blocco su di esso, se lo desidero.