【问题标题】:SQL Transactions (b)locking Selects - is my understanding correctSQL Transactions (b)locking Selects - 我的理解正确吗
【发布时间】:2009-04-06 07:26:45
【问题描述】:

我们正在使用 ADO.NET 连接到 SQL 2005 服务器,并在其中执行一些插入/更新和选择。我们将其中一项更新更改为在事务中,但是当我们执行此操作时,它似乎 (b) 锁定了整个表,而不管我们在事务上设置的 IsolationLevel。

我似乎看到的行为是:

  1. 如果您没有交易,那就是一场全面的战斗(失败者被锁定)
  2. 如果您有几笔交易,那么他们会一直赢,并阻止所有其他交易,除非
  3. 如果您有一些事务并且您在其余事务上设置了类似 nolock 的设置,那么您将获得事务并且没有任何阻塞。 这是因为每个语句(选择/插入/删除/更新)都有一个隔离级别,而与事务无关

这对吗?

【问题讨论】:

    标签: sql sql-server transactions locking


    【解决方案1】:

    您的问题的答案是:视情况而定。

    如果您要更新表,SQL Server 使用多种策略来决定要锁定多少行,行级锁定、页锁定或全表锁定。

    如果您要更新超过一定百分比的表(我记得可以配置),那么 SQL Server 会为您提供表级锁,这可能会阻止选择。

    最好的参考是:

    祝你好运。

    【讨论】:

      【解决方案2】:

      您的更新语句(即更改数据的语句)将持有锁,无论隔离级别如何,以及您是否明确定义了非事务。

      您可以使用query hints 控制锁的粒度。因此,如果更新锁定了整个表,那么您可以指定查询提示以仅锁定受影响的行(ROWLOCK 提示)。除非您的查询当然是更新整个表。

      因此,为了回答您的问题,请求资源锁定的第一个连接将在事务期间持有这些锁定。您可以通过使用未提交的读取隔离级别指定选择不持有锁,更改数据插入/更新/删除的语句始终持有锁。下一个请求锁定同一资源的连接将等到第一个连接完成,然后将持有它的锁。死锁是一种特殊情况,其中两个连接持有锁,每个连接都在等待另一个连接的资源,为了避免引擎永远等待,选择一个连接作为死锁牺牲品。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-04
        • 2012-01-27
        • 2021-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多