2016-11-15 44 views
0

如果有一个表约几个用户数寄存器,例如,像这样:使用sp_getapplock可以锁定数据资源吗?

create table test (id int identity, userid int, data nvarchar(max)); 

insert into test (userid, data) 
      select 1, 'aaa' 
union all select 1, 'bbb' 
union all select 2, 'ccc' 
union all select 3, 'ddd' 
union all select 3, 'eee'; 

并多次进程中运行以下更新:

update test 
set data = data + 'z' 
where userid = 1; 

根据更新的执行计划查询有可能一个更新开始在方向上更新,而另一个更新将导致死锁。

为了防止出现这种情况,不锁定整个表格,也许可以使用sp_getapplock并锁定资源'userid_1'。这样,只有一个进程可以更新每个用户,但是多个进程仍然可以并行更新其他用户(sp_getapplock'userid_3'等)。

begin transaction 

sp_getapplock @Resource = 'userid_1', @LockMode = 'Exclusive'; 

update test 
set data = data + 'z' 
where userid = 1; 

sp_releaseapplock @Resource = 'userid_1'; 

commit transaction 

sp_getapplock能够喜欢这个工作,对许多用户?

我问这个,因为我发现使用sp_getapplock对应用程序资源锁定像'form_1',也许这可能意味着sp_getapplock的例子并不需要扩展到大量的资源(如100K用户对不同的用户10锁定在每一刻)。

我会测试这个,但想知道我是否做错了什么。

注意:我考虑添加一个user表只是为了在事务中用一些虚拟数据更新用户记录以获得相同的效果,但它听起来并不正确。

回答

0

这取决于你的意思是“规模好”。你本质上是为你的数据库中的一个逻辑实体(在你的例子中是一个用户)推出自己的互斥锁。在第一个之后调用获取互斥体会阻塞,直到互斥体被释放(或者拥有范围结束,此时隐式释放互斥体)。这本质上会降低并发性,但我会争辩说,这就是你想要做的。但是要回答有关资源使用情况的问题,应用程序锁使用与用于锁定表或数据页的基础结构相同的基础结构。唯一的区别是你明确地控制它。

相关问题