有人可以解释一下进程如何获取页面上的SIX
锁定吗?我的死锁图xml文件我看到在 RC隔离级别下运行的进程(在死锁时执行select
语句)在页面上保持SIX
锁定。
这意味着什么以及如何获得锁定?
根据我从http://msdn.microsoft.com/en-us/library/aa213039%28v=sql.80%29.aspx SIX
获得的锁保护S
- 锁定所有资源,并在层次结构中较低的某些资源上锁定IX
。
我的情况是IX
- 锁定行? IX
- 锁可以放在一行吗? (我觉得不是)。我很困惑。
另一件事是我希望有几个X
- 锁定行而不是S
- 完全锁定(因为 IL 是 ReadCommited )。如果我只在前面的语句中插入了几条记录,为什么我用SIX
锁定了整个页面?
起来!
答案 0 :(得分:3)
通过Sebastian Meine来回答dba:
要回答我必须绕道而行,所以请耐心等待。 如果两个会话锁定同一资源,则SQL Server会检查锁兼容性映射,如果第二个请求与第一个请求不兼容,则第二个会话必须等待。有三种锁定类型“S”hared,“U”pdate和e“X”cluster。 S锁用于从资源读取,并且X锁用于写入资源。 S锁彼此兼容,X锁与其他任何东西都不兼容。 U锁是一种混合,在某些情况下用于防止死锁。
现在,SQL Server可以在几个级别上进行锁定:表,分区,页面和行。因此,如果会话1采用表锁并且会话2在表的一行上采用不兼容的锁,则这两个锁不在同一资源上,并且SQL Server将不会检测到冲突。为了防止这种情况,SQL Server始终开始在表级别上锁定并沿着层次结构向下工作。现在页面和行锁的点是更高的并发性,因此如果一个会话想要写入一行而另一个会话想要写入另一行,则它们不应该相互阻塞。如果一个会话除了对一行进行锁定之外还必须对表进行相同的锁定,那么这种优势就会消失。因此,会话不是在表上采用独占锁(X),而是请求一个打算独占锁(IX)。此锁与其他打算锁兼容,但与其他“实际”锁不兼容。因此,另一个会话也可以在同一个表上进行打算独占锁定。意图排他锁说,会话打算对较低级别的资源进行独占锁定。如果预期的锁是行锁,则在页面级别上也会发生相同的情况,因此在完成所有操作后,会话在表上和其中一个页面上有一个IX锁,并且该页中的一行上有一个X锁。这也意味着,您永远不会在行上找到意图锁定,因为行是锁定层次结构中的最低级别。
在某些情况下,会话在表或页面上持有S锁。如果会话现在(在同一个事务中)请求对同一个表中的行进行X锁定,则首先必须对表/页面进行IX锁定。但是,会话只能在任何给定资源上保留一个锁。因此,要采用IX锁,它必须释放可能不需要的S锁,因此SQL Server提供了一个组合:SIX。
您有页面锁定的原因是SQL Server有时会决定锁定页面而不是锁定每一行更好。如果已经在会话之间进行了很多锁定,那么这种情况经常发生,但也可能有许多其他原因。
到目前为止的理论。
现在,在您的情况下,SIX锁由三个表连接选择查询保持。除非您明确告诉它(例如,使用XLOCK提示),否则select永远不会采用任何类型的非共享锁的锁。这样的提示在输入缓冲区中是不可见的,因此我假设IX部分是此连接上最后一批的剩余部分。如果您正在使用连接池并忘记清除所有打开的事务,那么这样的锁可能永远存在。但是排除故障也很困难。
你可以先运行一个XENvent会话,将OPEN TRAN与COMMIT配对,看看你是否能找到那种罪魁祸首。
来源:https://dba.stackexchange.com/questions/45284/understanding-six-lock-in-microsoft-sql-server