SQL Transactions(b)锁定选择 - 我的理解是正确的

时间:2009-04-06 07:26:45

标签: sql sql-server transactions locking

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

我似乎看到的行为是:

  1. 如果你没有交易那么这是一场全力以赴的战斗(失败者被锁死)
  2. 如果您有一些交易,那么他们会一直赢,并阻止所有其他交易,除非
  3. 如果您有一些交易并且您在其余部分设置了类似nolock的内容,那么您将获得交易并且不会阻止任何事务。 这是因为每个语句(select / insert / delete / update)都有一个隔离级别,而不管事务
  4. 这是对的吗?

2 个答案:

答案 0 :(得分:2)

你的问题的答案是:这取决于。

如果要更新表,SQL Server使用多种策略来决定要锁定的行数,行级锁,页锁或完整表锁。

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

最好的参考是:

祝你好运。

答案 1 :(得分:1)

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

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

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