2011-03-09 190 views
1

好吧,我已經閱讀了大量關於SQL Server鎖定的內容,但我很努力地理解這一切。SQL Server 2008 Express鎖定

我想實現這樣的:

我需要能夠當用戶A選擇它來鎖定一個行

如果用戶B然後嘗試選擇它,我的WinForms .NET應用程序需要將相關表單上的所有控件設置爲禁用,以便用戶無法嘗試和更新。如果我可以爲用戶B拋出一個消息框,說明用戶A是使用該行的人,這也會很好。

所以基本上用戶B需要能夠選擇數據,但是當他們這樣做時,他們也應該得到a)記錄是否被鎖定以及b)誰鎖定了它。

我知道人們會說我應該讓SQL Server處理鎖定,但我需要用戶B知道該記錄在他們選擇它時儘快使用,而不是在他們更新時發現 - 通過哪些時間他們可能已經將數據輸入到表單中,從而導致不一致。

此外,任何鎖都需要允許SELECT仍然發生 - 所以當用戶B做他的SELECT時,而不是僅僅拋出一個異常並且收不到/不完整的數據,他仍然應該獲取數據並且能夠查看它,但只是無法更新它。

我猜這是非常基本的東西,但是有太多與SQL Server的鎖定有關的術語,我不熟悉,因爲它使目前的閱讀非常困難。

感謝

+0

就SQL Server而言,鎖定是僅當用戶B想要做某事時相關對象參與某種事務的情況下才適用(並且只發生)的事情。您似乎在描述您希望應用程序管理的內容。 – sasfrog 2011-03-09 12:24:07

+1

您需要實施[Pessimistic Offline Lock](http://martinfowler.com/eaaCatalog/pessimisticOfflineLock.html)模式。 – Arjen 2011-03-09 12:45:27

+0

這個問題的名稱並不真正符合要求,這會導致無用的搜索結果項目。 – 2011-05-11 00:50:23

回答

1

這不是真正的SQL Server的鎖定是什麼 - 最好你應該只保留一個交易(因此鎖)打開來完成針對數據庫的原子操作所需要的絕對最低 - 你當然不應該在等待用戶輸入時持有鎖。

通過(例如)將locked位列與locked_by varchar列一起添加到列,可以更好地跟蹤這些類型的鎖,以跟蹤誰鎖定了行。

首先用戶應UPDATE該行表示該行被鎖定,誰擁有它鎖:

UPDATE MyTable 
SET `locked` = 1 
AND `locked_by` = @me 
WHERE `locked` = 0 

locked = 0檢查是否有防止潛在的競爭條件,並確保你不不更新其他人已經鎖定的記錄。

這個第一個用戶然後做一個SELECT返回數據,並確保他們確實設法鎖定行。

+0

我確實已經考慮過這樣做了,但是想知道是否還有其他內置的東西會爲我做。顯然不是。謝謝! – 2011-03-09 13:25:42

2

要創建這種'應用程序鎖定',您可能需要使用名爲Locks的表格,並在其中插入密鑰,用戶標識和表格名稱。

當您的選擇出現時,加入鎖表並使用此值的存在來指示記錄被鎖定。

我還建議添加一個'RowVersion'列到您希望保護的表格中。該字段將有助於識別您是否正在更新或查詢自上次選擇它以來發生更改的行。