如何在SQL Server中更改锁定策略?

5
3个回答

5

您可以通过阅读基于行版本控制的隔离级别来了解如何使用ALTER命令进行设置,并附有示例。

它是在数据库级别上进行设置的,具体如下:

ALTER DATABASE YourDatabaseName SET READ_COMMITTED_SNAPSHOT ON;

更好的起点是上述文档的父级,该文档涵盖相关主题:基于行版本控制的数据库引擎隔离级别
编辑:添加了下面评论中提到的链接。

好的,那么我该如何查看当前的隔离级别呢? 这个隔离级别仅适用于运行在事务中的查询,还是所有查询都适用? - Allrameest
1
您可以运行DBCC USEROPTIONS,其中返回的项目之一将是“隔离级别”的当前设置。这是MSDN链接:http://msdn.microsoft.com/en-us/library/ms180065.aspx。 - Ahmad Mageed
关于您问题的第二部分,要在事务中使用隔离级别,您需要在“BEGIN TRAN”语句之前使用“SET TRANSACTION ISOLATION LEVEL SNAPSHOT”来明确设置它。因此,我的理解是它只影响您明确声明其为事务查询的查询。上面链接中有一个示例。这里还可以阅读一篇很好的文章来解释这个问题:http://www.databasejournal.com/features/mssql/article.php/3566746/Controlling-Transactions-and-Locks-Part-5-SQL-2005-Snapshots.htm - Ahmad Mageed
使用快照隔离级别会在数据库负载增加时给tempdb带来很大的负担。 - mrdenny
1
+1 这似乎是 Stack Overflow 自己使用的设置,参见 http://www.codinghorror.com/blog/archives/001166.html - Andomar

1

使用SNAPSHOT隔离级别会在数据库负载增加时增加tempdb的负担。

最好通过查询中的锁定提示或通过更改存储过程或连接的ISOLATION LEVEL来更改锁定方法。这可以通过SET ISOLATION LEVEL命令完成,或者通过更改.NET中的连接对象上的隔离级别来完成。

如果您希望SQL Server在非默认页面级别(即行级锁定)处理其锁定,必须通过在语句中使用WITH(ROWLOCK)提示逐个处理。

UPDATE YourTable WITH (ROWLOCK)
   SET Col2 = 3
WHERE Col1 = 'test'

没有全局设置可以更改此锁定级别,如果在快照隔离级别中与ROWLOCK结合使用,则操作仍将在页面级别上进行,因为整个页面必须被复制到tempdb数据库中,然后更新,然后旧版本必须从tempdb数据库中删除。


你不能通过SET ISOLATION LEVEL或.NET连接对象选择“READ_COMMITTED_SNAPSHOT”。你必须像Ahmad Mageed的回答一样使用ALTER DATABASE。 - Andomar
@Andomar 如果您要使用SNAPSHOT,则必须在数据库级别启用它。为了使您的事务使用它,您仍然必须使用SET TRANSACTION ISOLATION LEVEL SNAPSHOT将该事务的隔离级别设置为使用SNAPSHOT,而不是始终是默认值的READ COMMITTED。 - mrdenny

0

您可以在建立到数据库的连接时通过调用设置锁定隔离级别

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 

我工作的地方,我们为每个连接都这样做,它们都在同一个地方设置,因为我们使用共享连接池来访问数据库。然后,读未提交选项适用于该连接发出的所有语句。


嗯,我不建议在整个数据库上设置“READ UNCOMMITTED” - 这实际上取决于您对数据库的使用。 SQL Server 2005+支持快照隔离,基本上以类似于Oracle的方式对行进行版本控制。 - pjp
你把“读取已提交的快照”和“读取未提交的数据”搞混了。前者是一个相对较少使用的设置,你不能通过“set transaction isolation level”来选择它,可以参考Ahmad Mageed的帖子。 - Andomar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接