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

时间:2013-03-12 17:50:17

标签: sql-server deadlock trace read-committed-snapshot snapshot-isolation

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

  1. 第一笔交易在交易开始时获得一个序列号。
  2. 第二个在事务开始时得到一个后来的序列号,但在第一个事务已经得到它之后(第二个序列号比第一个更新)。
  3. 第二个事务首先进入更新语句。当它检查行版本控制时,它会看到两个事务之前的记录,因为第一个事务尚未到达更新。它发现行的序列号处于一个已提交的状态,并以它的快乐方式移动。
  4. 第一个事务轮到它,就像第二个事务找到相同的已提交序列号一样,因为它不会看到第二个事务,因为它比它本身更新。当它尝试提交时,发现另一个事务已经更新了正在尝试提交的记录,并且必须自行回滚。
  5. 以下是我的问题:此回滚是否会在跟踪中显示为死锁?

3 个答案:

答案 0 :(得分:2)

在原始问题附带的评论中,您说:“我只是想知道更新冲突是否会出现死锁或是否会出现不同的情况。”当我开始研究使用快照隔离时,我确实有这些类型的问题。最后我意识到READ_COMMITTED_SNAPSHOT和隔离级别SNAPSHOT之间存在显着差异。

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

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

答案 1 :(得分:0)

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

 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.

答案 2 :(得分:-1)

防止死锁启用

ALLOW_SNAPSHOT_ISOLATION和READ_COMMITTED_SNAPSHOT

ALTER DATABASE [BD] SET READ_COMMITTED_SNAPSHOT ON; ALTER DATABASE [BD] SET ALLOW_SNAPSHOT_ISOLATION ON;

这里解释了差异 http://technet.microsoft.com/en-us/sqlserver/gg545007.aspx