【问题标题】:How to change locking strategy in SQL Server?如何更改 SQL Server 中的锁定策略?
【发布时间】:2023-03-25 13:35:01
【问题描述】:

我读过这样的文章: http://www.codinghorror.com/blog/archives/001166.html http://www.databasejournal.com/features/mssql/article.php/3566746/Controlling-Transactions-and-Locks-Part-5-SQL-2005-Snapshots.htm

据我了解,SQL Server 有一个非常悲观的锁定策略。为了提高性能,我应该更改锁定的已提交读快照。

但我找不到在哪里执行此操作。在哪里更改锁定策略?

【问题讨论】:

    标签: sql-server performance locking deadlock


    【解决方案1】:

    您可以在Using Row Versioning-based Isolation Levels 上阅读有关如何使用 ALTER 命令设置它们的示例。

    在数据库级别设置如下:

    ALTER DATABASE YourDatabaseName SET READ_COMMITTED_SNAPSHOT ON;
    

    更好的起点是上述文档的父级,它涵盖了相关主题:Row Versioning-based Isolation Levels in the Database Engine

    编辑:添加了下面我的 cmets 中提到的链接。

    【讨论】:

    • 好的,但是我如何查看当前的隔离级别?这种隔离级别是仅适用于在事务中运行的查询,还是适用于所有查询?
    • 您可以运行 DBCC USEROPTIONS,返回的项目之一将是“隔离级别”的当前设置。这是 MSDN 链接:msdn.microsoft.com/en-us/library/ms180065.aspx
    • 关于问题的第二部分,要在事务中使用隔离级别,您需要在“BEGIN TRAN”语句之前使用“SET TRANSACTION ISOLATION LEVEL SNAPSHOT”专门设置它。因此,我的理解是它只影响您明确声明它的事务查询。上面的链接就是一个例子。一篇很好的文章也可以在这里阅读:databasejournal.com/features/mssql/article.php/3566746/…
    • 随着数据库负载的增加,使用 SNAPSHOT 隔离级别会增加大量的 tempdb 负载。
    • +1 这就是 Stack Overflow 本身似乎使用的设置,见codinghorror.com/blog/archives/001166.html
    【解决方案2】:

    随着数据库负载的增加,使用 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 数据库中删除旧版本。

    【讨论】:

    • -1 您不能通过 SET ISOLATION LEVEL 或通过 .NET 连接对象选择“READ_COMMITTED_SNAPSHOT”。你必须改变数据库,就像 Ahmad Mageed 的回答一样。
    • @Andomar 是的,如果您要使用 SNAPSHOT,您必须在数据库级别启用它。为了让您的事务使用它,您仍然必须使用 SET TRANSACTION ISOLATION LEVEL SNAPSHOT 作为该事务的隔离级别,以使用 SNAPSHOT 而不是 READ COMMITTED,这始终是默认值。
    【解决方案3】:

    您可以在设置与数据库的连接时设置锁隔离级别,方法是调用

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 
    

    在我工作的地方,我们对设置的每个连接都执行此操作,它们都设置在同一个位置,因为我们使用共享连接池访问数据库。然后,READ UNCOMMITTED 选项适用于该连接发出的所有语句。

    【讨论】:

    • 嗯,我不建议全面设置READ UNCOMMITTED - 这实际上取决于您对数据库的使用情况。 SQL Server 2005+ 支持快照隔离,它以类似于 Oracle 工作方式的方式对行进行本质上的版本化。
    • 您将“已提交的读取快照”与“未提交的读取”混淆了。前者是一个相对未知的设置,您无法通过“设置事务隔离级别”进行选择,请参阅 Ahmad Mageed 的帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    相关资源
    最近更新 更多