2015-10-20 49 views
0

我想在sql表中打開一個表時鎖定一行,同時另一個用戶打開相同的記錄方式,它應該以只讀模式打開。在sql表中鎖定記錄

例如: 我有一個客戶表,我以用戶A的身份登錄,並且正在編輯客戶的xyz記錄(行),同時另一個用戶B登錄並嘗試編輯記錄,但用戶B不應編輯記錄(即使頁面不應爲空)。

我該怎麼做這個?

+1

檢測行被鎖定可以完成,但並不簡單(有不同種類的鎖)。有關更多信息,請參閱http://stackoverflow.com/q/7436935/67392。但是,檢測鎖定可能是錯誤的方法:在用戶打開某些東西時保持數據庫鎖定會導致您的可伸縮性喪失。 – Richard

+0

另外:如果您真的想這樣做,我的SQL和SQL Server將需要完全不同的解決方案:您真的想要兩個? – Richard

+0

我會做手動,例如把一個多列「IsLocked」,然後你可以通過像AcquireLock(customerId)的函數或存儲過程管理該鎖... – mecek

回答

1

一種方法是在編輯記錄時使用位字段編輯並將其賦值爲true。在應用程序級別,不允許在編輯模式下編輯記錄。您在那裏遇到的問題是某人正在編輯並將其留在那裏,因此您需要有一個超時來清除編輯模式。並且可能跟蹤誰將其置於編輯模式。

+0

這將工作,但我仍然會使用數據庫事務,並在實際更新數據庫之前檢查位列,然後關閉位列,然後結束事務。 –

+0

感謝您的答覆飛盤。 – Karthikeyan

1

我們曾經使用過的產品有一張表,當放置鎖時,這張表保持不變。在他們的系統中,主鍵總是一個整數。所以,表格非常簡單:會話標識符,表名,行鍵。當一個人進入記錄時,運行一個試圖插入鎖的程序。如果該行已經存在,那麼該人將只能看到。否則,會將一行添加到鎖定表中,授予會話權限進行編輯。一旦記錄退出,該行就從鎖定表中刪除。

如果應用程序在沒有使用正確的退出機制的情況下關閉(他們必須點擊退出屏幕),我們會得到被鎖定的記錄。我們寫了一個方法來清除這些鎖定行。我們要求原始開發者在應用程序終止時清除所有的會話,但無法添加它。

我會嘗試將過期時間放在鎖定表中,以便根據需要將其清除。雖然您無法保證應用程序總是會乾淨地退出,但嘗試包括某些內容以清除所有正常應用程序退出的編輯鎖定。

1
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 
} 

使用它們通過這種方式,更新語句應在內部處理的悲觀鎖定可能的情況。

+0

感謝您的回覆Mecek – Karthikeyan