SQL Server 2008 R2中,使用SNAPSHOT隔离级别进行写操作是否会阻塞另一个SNAPSHOT事务的写操作?

7
在SQL Server 2008 R2中,对于SNAPSHOT隔离级别,在MSDN ADO.Net文档中提到了以下内容:
“修改数据的事务不会阻塞读取数据的事务,读取数据的事务也不会阻塞写入数据的事务,这与SQL Server默认的READ COMMITTED隔离级别下通常的情况不同。”
在两个事务都处于SNAPSHOT隔离模式时,没有提到写入是否会阻塞写入。因此我的问题如下: 在一个SNAPSHOT事务1中,对相同表格的写入是否会阻塞另一个SNAPSHOT事务2的写入? 最新更新 在思考了很多关于我的问题后,我得出了以下结论。希望其他人能够更深入地解释。
没有任何关系型数据库可以使写入不阻塞写入”。换句话说,写入将始终阻塞写入。写入包括INSERT、UPDATE或DELETE语句。这适用于所有隔离级别,因为所有关系型数据库都需要在数据库中发生多个写入时实现数据一致性。当然,同时进行的写入需要发生冲突(例如插入到相同的表格或更新相同的行),才会发生阻塞。

参见:https://dev59.com/RkjSa4cB1Zd3GeqPDClN - StuartLC
2个回答

5
Ligos的说法是不正确的——如果两个独立的事务尝试使用快照模式更新相同的记录,则事务2将被阻塞,直到事务1释放锁为止。只有在此之后,才会收到错误3960。我意识到这个主题已经过了2年,但我想避免出现错误信息。

即使是Ligos引用的链接也说了和我上面提到的完全一样的事情(请查看最后一个非红色段落)

如果尝试更新的两条记录(即行)不同,则“写入”与“写入”将不会被阻塞。


3
不会阻塞,而是在“trans2”中的“UPDATE”命令将失败,并显示错误编号3960。由于“SNAPSHOT”隔离级别的工作方式,任何“UPDATE”命令都可能失败。唯一能确定的方法是捕获和处理错误3960(这称为乐观并发性,因为您不希望这种情况经常发生)。我最终进行了经验性测试,因为从文档中并不完全明显。但此博客文章很好地说明了这一点。
假设: trans1trans2 都在更新同一张表中的同一行。更新两个不同的行应该没有问题。

igos - 感谢您的回复。如果有两个带有INSERTS的SNAPSHOT事务,它们会相互阻塞吗?因为它们都试图插入新行。 - Sunil
@Sunil,INSERT 不应该相互阻塞(假设您没有尝试插入相同的主键)。 - ligos
@Sunil 在阅读了你的更新后,INSERT 不会死锁彼此(假设有不同的主键)。它们可能会暂时阻塞,因为新的标识键被创建并且数据实际上被写入,但它们不会死锁或者阻塞等待表锁。UPDATE 会死锁。我没有尝试测试 DELETE(因为我很少使用它们),但我怀疑它们会类似于 UPDATE - ligos
ligos - 再次感谢您的回复。我认为在插入一行或几行时,阻塞是微不足道的。但是当像将5,000行插入表中这样大量插入时,在SNAPSHOT隔离级别下会阻止其他插入/更新操作。这就是我们在我们这边观察到的情况。 - Sunil
博客文章链接现在很遗憾已经失效。 - MgSam

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