是否可以在SQL Server中强制执行行级锁定?

Ela*_*lan 54 sql-server sql-server-2005 sql-server-2008 rowlocking

我可以看到如何关闭SQL Server中的行级和页级锁定,但我找不到强制SQL Server使用行级锁定的方法.有没有办法强制SQL Server使用行级锁定而不使用页面级锁定?

Sam*_*ron 32

您可以使用ROWLOCK提示,但如果资源不足,AFAIK SQL可能会决定对其进行升级

来自doco:

ROWLOCK指定在通常采用页锁或表锁时获取行锁.在以SNAPSHOT隔离级别操作的事务中指定时,除非将ROWLOCK与需要锁定的其他表提示(例如UPDLOCK和HOLDLOCK)组合,否则不会进行行锁定.

锁提示获取行级锁的ROWLOCK,UPDLOCK和XLOCK可能会锁定索引键而不是实际数据行.例如,如果表具有非聚簇索引,并且使用锁定提示的SELECT语句由覆盖索引处理,则会在覆盖索引中的索引键上获取锁定,而不是在基表中的数据行上获取锁定.

最后,这给出了SQL Server 2005中锁定升级的深入解释,该升级在SQL Server 2008中已更改.

还有,非常深入:锁定数据库引擎(在线书籍)

所以,总的来说

UPDATE
Employees WITH (ROWLOCK)
SET Name='Mr Bean'
WHERE Age>93
Run Code Online (Sandbox Code Playgroud)

应该没问题,但根据服务器上的索引和负载,它可能最终升级为页锁.

  • 只是添加,在sql server 2008+中你可以用`ALTER TABLE tableName SET(LOCK_ESCALATION = DISABLE)来有效地禁用锁升级. (10认同)
  • “它最终可能会升级为页面锁定。” 根据 BOL,这是不可能的:“数据库引擎不会将行或键范围锁定升级为页面锁定” http://technet.microsoft.com/en-us/library/ms184286(v=sql.105).aspx (2认同)

Rem*_*anu 14

使用ALTER/CREATE INDEX的ALLOW_PAGE_LOCKS子句:

ALTER INDEX indexname ON tablename SET (ALLOW_PAGE_LOCKS = OFF);
Run Code Online (Sandbox Code Playgroud)

  • @Sam:详情;)广告中的真相:我绝不会**在我的数据库上关闭它.解决方案始终是正确设计架构和查询,以便在开始时不会发生扫描(这是升级的罪魁祸首)... (9认同)
  • 一个重要的注意事项是,如果资源不足,这可能会升级为表锁 (4认同)

mdm*_*dma 8

您无法强制优化器执行任何操作,但您可以指导它.

UPDATE
Employees WITH (ROWLOCK)
SET Name='Mr Bean'
WHERE Age>93
Run Code Online (Sandbox Code Playgroud)

请参阅 - 使用锁定和提示控制SQL Server