0

我无法弄清楚为什么会发生这种情况。很确定我理解这个理论,但是我看不到的东西肯定在发生。

表 A 具有以下架构:

ID [Primary Key]
Name
Type [Foreign Key]

SprocA 将隔离级别设置为可重复读取,并从表 A 中选择具有Type=1. 它还会更新这些行。

SprocB 从表 A 中选择具有Type=2.

现在鉴于这些是完全不同的行集,如果我同时执行两者(并放WAITFOR调用以减慢它的速度),SprocB 直到 SprocA 才会完成。

我知道这与对类型的查询有关,就好像我根据主 ID 进行选择一样,它允许并发访问表。

任何人有任何启示?

干杯

4

3 回答 3

1

SQL Server 使用索引来执行范围锁(这是可重复读取经常使用的),因此如果您没有 Type 上的索引,它可能会锁定整个表......

于 2009-11-04T18:55:05.873 回答
1

为隔离级别设置可重复读取后,您将对读取的所有数据持有共享锁,直到事务完成。直到你提交或回滚。

这将降低您的应用程序访问此数据的并发性。因此,如果您的第一个过程从表中选择然后调用 WAITFOR 然后在事务中再次选择等,您将一直持有共享锁,直到您提交事务或过程完成。

如果这是您正在使用的测试过程,请尝试在每次选择后添加一个 COMMIT 并查看这是否有助于第二个过程同时运行。

祝你好运!

凯文

于 2009-11-04T19:09:36.057 回答
0

要记住的是,锁定的行对于其他进程来说是黑盒子。

你知道 SprocA 只是读取 type = 1 的值,而 SprocbB 只是读取 type = 2 的值。

但是,SprocB 不知道 SprocA 将对这些记录做什么。在事务完成之前,SprocA 可能将所有记录更新为 type = 2。在这种情况下,如果 SprocB 不等待 SprocA 完成,它将无法正常工作。

在执行范围锁定/批量更改时保持并发性很困难。

于 2009-11-04T19:20:05.510 回答