读提交快照隔离:更新冲突回滚是否显示为死锁?



我已经读取了提交的快照隔离,并允许对数据库进行隔离ON。我仍然收到死锁错误。我很确定我知道发生了什么……

  1. 第一个事务在其事务开始时获得序列号。
  2. 第二个在事务开始时获得较晚的序列号,但在第一个事务已经获得其序列号之后(第二个序列号比第一个更近)。
  3. 第二个事务首先进入update语句。当它检查行版本控制时,它会看到两个事务之前的记录,因为第一个事务尚未达到更新。它发现行序列号处于已提交状态,并继续前进。
  4. 第一个事务轮到它了,像第二个事务一样,它发现了相同的提交序列号,因为它不会看到第二个,因为它比自己新。当它试图提交时,它发现另一个事务已经更新了试图提交的记录,并且必须回滚自己。

我的问题是:这个回滚会在跟踪中显示为死锁吗?

在原始问题的评论中,您说:"我只是想知道更新冲突是否会出现死锁,或者是否会出现不同的东西。"当我开始研究使用快照隔离时,我实际上就有这些类型的担忧。最后,我意识到READ_COMMITTED_SNAPSHOT和隔离级别SNAPSHOT之间存在显著差异。

前者对读操作使用行版本控制,但对写操作继续使用排他锁。因此,READ_COMMITTED_SNAPHOT实际上是介于纯悲观和纯乐观并发控制之间的东西。因为它使用锁进行写入,所以不可能发生更新冲突,但可能发生死锁。至少在SQL Server中,这些死锁将被报告为死锁,就像它们在"正常"悲观锁定中一样。

后者(隔离级别SNAPSHOT)是纯乐观并发控制。行版本控制用于读和写。死锁是不可能的,但更新冲突是可能的。后者报告为更新冲突,而不是死锁。

回滚快照事务,并收到以下错误消息:

 Msg 3960, Level 16, State 4, Line 1
 Snapshot isolation transaction aborted due to update conflict. You cannot use snapshot
 isolation to access table 'Test.TestTran' directly or indirectly in database 'TestDatabase' to
 update, delete, or insert the row that has been modified or deleted by another transaction.
 Retry the transaction or change the isolation level for the update/delete statement.

为了防止死锁,

ALLOW_SNAPSHOT_ISOLATION and READ_COMMITTED_SNAPSHOT

ALTER DATABASE [BD] SET READ_COMMITTED_SNAPSHOT ONALTER DATABASE [BD] SET ALLOW_SNAPSHOT_ISOLATION

这里的

解释了它们的区别http://technet.microsoft.com/en-us/sqlserver/gg545007.aspx

相关内容

  • 没有找到相关文章

最新更新