我想在sql表中打開一個表時鎖定一行,同時另一個用戶打開相同的記錄方式,它應該以只讀模式打開。在sql表中鎖定記錄
例如: 我有一個客戶表,我以用戶A的身份登錄,並且正在編輯客戶的xyz記錄(行),同時另一個用戶B登錄並嘗試編輯記錄,但用戶B不應編輯記錄(即使頁面不應爲空)。
我該怎麼做這個?
我想在sql表中打開一個表時鎖定一行,同時另一個用戶打開相同的記錄方式,它應該以只讀模式打開。在sql表中鎖定記錄
例如: 我有一個客戶表,我以用戶A的身份登錄,並且正在編輯客戶的xyz記錄(行),同時另一個用戶B登錄並嘗試編輯記錄,但用戶B不應編輯記錄(即使頁面不應爲空)。
我該怎麼做這個?
一種方法是在編輯記錄時使用位字段編輯並將其賦值爲true。在應用程序級別,不允許在編輯模式下編輯記錄。您在那裏遇到的問題是某人正在編輯並將其留在那裏,因此您需要有一個超時來清除編輯模式。並且可能跟蹤誰將其置於編輯模式。
這將工作,但我仍然會使用數據庫事務,並在實際更新數據庫之前檢查位列,然後關閉位列,然後結束事務。 –
感謝您的答覆飛盤。 – Karthikeyan
我們曾經使用過的產品有一張表,當放置鎖時,這張表保持不變。在他們的系統中,主鍵總是一個整數。所以,表格非常簡單:會話標識符,表名,行鍵。當一個人進入記錄時,運行一個試圖插入鎖的程序。如果該行已經存在,那麼該人將只能看到。否則,會將一行添加到鎖定表中,授予會話權限進行編輯。一旦記錄退出,該行就從鎖定表中刪除。
如果應用程序在沒有使用正確的退出機制的情況下關閉(他們必須點擊退出屏幕),我們會得到被鎖定的記錄。我們寫了一個方法來清除這些鎖定行。我們要求原始開發者在應用程序終止時清除所有的會話,但無法添加它。
我會嘗試將過期時間放在鎖定表中,以便根據需要將其清除。雖然您無法保證應用程序總是會乾淨地退出,但嘗試包括某些內容以清除所有正常應用程序退出的編輯鎖定。
CREATE TABLE Customer
(
Id int,
Name nvarchar(max),
LockedOn DateTime
);
CREATE PROCEDURE dbo.AcquireLock (@customerId int)
AS BEGIN
Update Customer set LockedOn = GetDate() where [email protected]tomerId and LockedOn is Null
select @@ROWCOUNT
END
CREATE PROCEDURE dbo.ReleaseLock (@customerId int)
AS BEGIN
Update Customer set LockedOn = null where [email protected]
select @@ROWCOUNT
END
並在代碼中像
if (AcquireLock(customerId) > 0){
//yes you are editing it.
}
else{
//It is locked, you can not edit it
}
使用它們通過這種方式,更新語句應在內部處理的悲觀鎖定可能的情況。
感謝您的回覆Mecek – Karthikeyan
檢測行被鎖定可以完成,但並不簡單(有不同種類的鎖)。有關更多信息,請參閱http://stackoverflow.com/q/7436935/67392。但是,檢測鎖定可能是錯誤的方法:在用戶打開某些東西時保持數據庫鎖定會導致您的可伸縮性喪失。 – Richard
另外:如果您真的想這樣做,我的SQL和SQL Server將需要完全不同的解決方案:您真的想要兩個? – Richard
我會做手動,例如把一個多列「IsLocked」,然後你可以通過像AcquireLock(customerId)的函數或存儲過程管理該鎖... – mecek