如何执行行锁?

我想锁定一条记录,然后没有人可以对该记录进行更改。 当我释放锁定时,人们可能会更改记录。

在锁定记录的同时,我想向用户显示记录已被锁定且不允许更改的警告。

我怎样才能做到这一点?

我已经尝试了所有的IsolationLevel级别,但它们都没有我想要的行为。 一些隔离级别会等到锁定释放后再进行更改。 我不希望这样,因为在锁定记录时不允许更新。

如何锁定记录并拒绝所有更改?

我使用SQL Server 2008

假设这是MS SQL服务器,您可能需要UPDLOCK ,可能与ROWLOCK ( 表提示 )结合使用。 我找不到一篇描述理论的体面文章,但是这里有一个简单的例子:

 SELECT id From mytable WITH (ROWLOCK, UPDLOCK) WHERE id = 1 

此语句将在事务持续时间内对行进行更新锁定 (因此,了解事务何时结束非常重要)。 由于更新锁与独占锁 (更新记录所需) 不兼容 ,因此这将阻止任何人在事务结束之前更新此记录。

请注意,在事务完成之前,将阻止尝试修改此记录的其他进程,但是在事务结束后将继续执行它们请求的任何写入操作(除非它们作为死锁进程超时或终止)。 如果您希望阻止这种情况,那么您的其他进程需要使用其他提示,以便在检测到不兼容的锁时中止,或者如果记录已更改则跳过该记录。


此外, 您不应使用此方法在等待用户输入时锁定记录 。 如果这是你的意图,那么你应该在你的表中添加某种“被修改”列。

SQL服务器锁定机制实际上仅适用于保持数据完整性/防止死锁 – 事务通常应保持尽可能短,并且在等待用户输入时肯定不能维护。

Sql Server具有锁定提示,但这些提示仅限于查询范围。

如果在应用程序中决定锁定记录,则可以使用与乐观锁定相同的机制,并拒绝对应用程序中的记录进行任何更改。

使用时间戳或guid作为记录的锁定,如果给出了错误的锁定键,则拒绝访问或更改记录。 小心再次解锁记录,否则你会得到孤儿

在SO上看到这个重复的问题 。

基本上它是:

 begin tran select * from [table] with(holdlock,rowlock) where id = @id --Here goes your stuff commit tran 

档案

这样的事可能吗?

 update t set t.IsLocked = 1 from [table] t where t.id = @id 

在更新触发器的某处:

 if exists ( select top 1 1 from deleted d join inserted i on i.id = d.id where d.IsLocked = 1 and i.RowVersion <> d.RowVersion) begin print 'Row is locked' rollback tran end 

您不想等待锁定被释放并在遇到锁定时立即显示消息,如果是这种情况,那么您是否尝试过NOWAIT 。 有关更多详细信息,请参阅表提示(Transact-SQL)和SQL Server 2008表提示 。 要获得NOWAIT好处,您需要锁定编辑记录,谷歌了解更多详情。