アプリケーションに実装した簡単なソリューション ....
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 を持つレコードを選択します。
次に、呼び出しコードで、ロックが成功したかどうかを確認します。選択から返されたユーザー名と PC が、渡されたばかりのデータと一致する場合、ロックは成功です。ユーザー名は一致するが PC が一致しない場合、同じユーザーが別のマシンでレコードを開いています。ユーザー名が別のユーザーと一致しない場合は、既に開いています。 I.E このレコードは現在、ワークステーション XYZ の JoeB によってロックされています。
ユーザーがレコードを保存するか別の場所に移動するときは、レコード ロックを削除するだけです。
他の方法があると確信していますが、これは私にとってはうまくいきます。
更新
レコードが存在しない場合にのみ、レコードが挿入されます。次の select はレコードを返します。ユーザー名や PC が挿入しようとしたデータと異なる場合、レコードは別のユーザー (または別のマシンの同じユーザー) によって既にロックされています。したがって、1 回の呼び出しですべてが実行されます (いわば)。 Exec usp_LockRecord(1234, 'JoeB', 'Workstation1')
を呼び出すと、 返されたレコードは、そのレコードのロックに成功したデータと一致します。返されたユーザー名や PC が異なる場合、レコードは既にロックされています。次に、レコードがロックされていることを知らせるメッセージをユーザーに表示し、フィールドを読み取り専用にし、保存ボタンを無効にし、必要に応じて誰がレコードをロックしているかを伝えます。