SQL Server Rowlock通过选择如果不存在,则插入事务
-
30-09-2019 - |
题
我已经从SQL Server 2005升级到2008年。我记得在2005年,Rowlock根本不起作用,我不得不使用Pagelock或Xlock来实现任何类型的实际锁定。我知道读者会问“你做错了什么?”没有。我最终证明了我可以编辑“行”行,但是如果我升级锁定级别,则无法。我没有机会看看这在SQL 2008中是否有效。我的第一个问题是有人在2008年遇到这个问题吗?
我的第二个问题如下。我想测试是否存在值,如果是的,请对相关列进行更新,而不是整个行的插入。这意味着,如果发现该行需要锁定,因为维护过程可能会删除此行中过程,从而导致错误。
为了说明原则,以下代码可以工作吗?
BEGIN TRAN
SELECT ProfileID
FROM dbo.UseSessions
WITH (ROWLOCK)
WHERE (ProfileID = @ProfileID)
OPTION (OPTIMIZE FOR (@ProfileID UNKNOWN))
if @@ROWCOUNT = 0 begin
INSERT INTO dbo.UserSessions (ProfileID, SessionID)
VALUES (@ProfileID, @SessionID)
end else begin
UPDATE dbo.UserSessions
SET SessionID = @SessionID, Created = GETDATE()
WHERE (ProfileID = @ProfileID)
end
COMMIT TRAN
解决方案
一个解释...
- 行锁/pagelock是粒度
- Xlock是模式
粒度和隔离水平和模式是正交的。
粒度=什么是锁定=行,页,表(
PAGLOCK, ROWLOCK, TABLOCK
)隔离级=锁定持续时间,并发(
HOLDLOCK, READCOMMITTED, REPEATABLEREAD, SERIALIZABLE
)模式=共享/排他性(
UPDLOCK, XLOCK
)“组合”,例如
NOLOCK, TABLOCKX
Xlock会按照您的意愿锁定该行。 Rowlock/Pagelock不会。
不隶属于 StackOverflow