Просто решение, което внедрих в приложение...
CREATE TABLE RecordLocks(
[RecordId] [varchar](8) NOT NULL,
[UserName] [varchar](100) NOT NULL,
[datetimestamp] [smalldatetime] NOT NULL,
[PC] [varchar](100) NOT NULL
)
GO
datetimestamp
има по подразбиране GetDate()
RecordId
е VARCHAR
поради първичния ключ в таблицата, който заключвам (не е мой избор). Освен това тази таблица има очевидните индекси
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
Първо изтрийте и записи, по-стари от 2 часа (променете, за да отговарят)
Проверете дали няма запис, който вече заключва този за заключване, и ако не, поставете ключалката.
Изберете записа с RecordId, който ни интересува.
След това в кода за повикване проверете дали заключването е успешно. Ако потребителското име и компютърът, които се връщат от селекцията, съвпадат, данните, току-що предадени в заключването, бяха успешни. Ако потребителското име съвпада, но компютърът не, същият потребител има отворен запис на друга машина. ако потребителското име не съвпада, друг потребител вече го е отворил. Показвам съобщение на потребителя, ако неговият I.E е неуспешен. Този запис в момента е заключен от JoeB на работна станция XYZ.
Когато потребителят запази записа или навигира, просто изтрийте заключването на записа.
Сигурен съм, че има и други начини, но този работи добре за мен.
Актуализация
Запис ще бъде вмъкнат само ако не съществува. Следният избор ще върне запис. Ако потребителското име и/или компютърът са различни от данните, които се опитвате да вмъкнете, записът вече е заключен от друг потребител (или същия потребител на различна машина). Така че едно обаждане прави всичко (така да се каже). Така че, ако направя повикване Exec usp_LockRecord(1234, 'JoeB', 'Workstation1')
и записът, който получавам обратно, съвпада с тези данни, които успешно съм заключил на този запис. Ако потребителското име и/или компютърът, които получавам обратно, са различни, записът вече е заключен. След това мога да покажа съобщение на потребителя, уведомяващо записът да е заключен, да направя полетата само за четене, да деактивирам бутоните за запазване и да им кажа кой го е заключил, ако желая.