2011-03-09 240 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'列到您希望保护的表格中。该字段将有助于识别您是否正在更新或查询自上次选择它以来发生更改的行。