【问题标题】:Do writes in SNAPSHOT isolation level block writes in another SNAPSHOT transaction in SQL Server 2008 R2在 SQL Server 2008 R2 的另一个 SNAPSHOT 事务中写入 SNAPSHOT 隔离级别块写入
【发布时间】:2014-10-20 22:50:58
【问题描述】:

对于 SQL Server 2008 R2 中的 SNAPSHOt 隔离级别,MSDN ADO.Net 文档中提到了以下内容:

修改数据的事务不会阻塞读取数据的事务,读取数据的事务不会阻塞写入数据的事务,因为它们通常会在 SQL Server 中默认的 READ COMMITTED 隔离级别下阻塞。

当两个事务都处于 SNAPSHOT 隔离模式时,没有提及写入是否会阻塞写入。所以我的问题如下: 在一个 SNAPSHOT 事务1 中的写入会阻止写入另一个 SNAPHOT 事务2 中的相同表吗?

最新更新

在对我的问题进行了很多思考之后,我得出了如下段落所述的结论。希望其他人可以对此有所了解。

没有写入不会阻塞写入的关系数据库。换句话说,写入将总是阻塞写入。写入将包括诸如 INSERT 或 UPDATE 或 DELETE 之类的语句。无论您使用哪种隔离级别都是如此,因为当数据库中发生多次写入时,所有关系数据库都需要实现数据一致性。当然,同时写入需要有冲突(如插入同一个表或更新同一行)才能发生这种阻塞。

【问题讨论】:

标签: sql-server-2008-r2 isolation-level


【解决方案1】:

Ligos 实际上是不正确的 - 如果两个单独的事务试图在 Snapshot 开启的情况下更新同一记录,事务 2 将被阻止,直到事务 1 释放锁。然后,只有到那时,您才会收到错误 3960。我意识到这个帖子已经有 2 年以上的历史了,但我想避免出现错误信息。

即使 Ligos 引用的链接与我上面提到的完全相同(查看最后一个非红色段落)

只有在尝试更新的两条记录(即行)不同时,写入与写入才会被阻止

【讨论】:

    【解决方案2】:

    没有。他们不会阻止。相反,trans2 中的 UPDATE 命令将失败,错误号为 3960。

    由于SNAPSHOT 隔离级别的工作原理,任何UPDATE 命令都可能失败。唯一可以判断的方法是捕获并处理错误 3960(它被称为乐观并发,因为您不希望这种情况经常发生)。

    我最终根据经验对此进行了测试,因为这在文档中并不完全明显。 This blog post 很好地说明了这一点。


    假设:trans1trans2 都在更新同一个表中的同一行。更新两个不同的行应该可以正常工作。

    【讨论】:

    • igos - 感谢您的回复。两个带有 INSERTS 的 SNAPSHOT 事务怎么样?两者都试图插入新行。他们还会互相屏蔽吗?
    • @Sunil INSERTs 不应相互阻塞(假设您没有尝试插入相同的主键)
    • @Sunil 阅读您的更新后,INSERTs 不会互相死锁(假设不同的主键)。它们可能会在创建新的身份密钥并实际写入数据时暂时阻塞,但它们不会死锁或阻塞等待表锁。 UPDATEs 做。我没有尝试测试DELETEs(因为我很少使用它们),但我怀疑它们会类似于UPDATE
    • ligos - 再次感谢您的回复。我认为插入一行或几行时阻塞是微不足道的。但是当向表中插入数千行(例如 5,000 行)时,它会在 SNAPSHOT 隔离级别时阻止其他插入/更新。这就是我们最终观察到的结果。
    • 博客文章链接现在很遗憾地失效了。
    猜你喜欢
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 2014-09-27
    • 2012-03-10
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多