Proste rozwiązanie, które zaimplementowałem w aplikacji ....
CREATE TABLE RecordLocks(
[RecordId] [varchar](8) NOT NULL,
[UserName] [varchar](100) NOT NULL,
[datetimestamp] [smalldatetime] NOT NULL,
[PC] [varchar](100) NOT NULL
)
GO
datetimestamp
ma domyślną wartość GetDate()
RecordId
jest VARCHAR
ze względu na klucz podstawowy w tabeli, którą blokuję (nie mój wybór). Również ta tabela ma oczywiste indeksy
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
Najpierw usuń i wpisy starsze niż 2 godziny (zmień na odpowiednie)
Sprawdź, czy nie ma już żadnego rekordu blokującego ten, który ma zostać zablokowany, a jeśli nie, włóż blokadę.
Wybierz rekord z interesującym nas identyfikatorem RecordId.
Następnie w kodzie wywołującym sprawdź, czy blokada się powiodła. Jeśli nazwa użytkownika i komputer wracający z zaznaczenia pasują do danych, które właśnie przekazano w blokadzie, zakończyły się sukcesem. Jeśli nazwa użytkownika jest zgodna, ale komputer nie ma tego samego użytkownika, który ma otwarty rekord na innym komputerze. jeśli nazwa użytkownika nie pasuje, inny użytkownik już ją otworzył. Wyświetlam komunikat dla użytkownika, jeśli nie powiedzie się IE Ten rekord jest obecnie zablokowany przez JoeB na stacji roboczej XYZ.
Gdy użytkownik zapisze rekord lub odejdzie, po prostu usuń blokadę rekordu.
Jestem pewien, że są inne sposoby, ale dla mnie to działa dobrze.
Aktualizacja
Rekord zostanie wstawiony tylko wtedy, gdy taki nie istnieje. Następujące zaznaczenie zwróci rekord. Jeśli nazwa użytkownika i/lub komputer różnią się od danych, które próbujesz wstawić, rekord jest już zablokowany przez innego użytkownika (lub tego samego użytkownika na innym komputerze). Tak więc jedno połączenie załatwia wszystko (że tak powiem). Więc jeśli zadzwonię Exec usp_LockRecord(1234, 'JoeB', 'Workstation1')
a rekord, który otrzymam, pasuje do danych, w których udało mi się zablokować ten rekord. Jeśli nazwa użytkownika i/lub komputer, który otrzymam, jest inny, rekord jest już zablokowany. Mogę wtedy wyświetlić użytkownikowi komunikat informujący, że rekord jest zablokowany, ustawić pola tylko do odczytu, wyłączyć przyciski zapisywania i powiedzieć im, kto ma na nim blokadę, jeśli zechcę.