在快照隔离模式下无法使用READPAST

时间:2010-04-14 16:21:15

标签: sql-server concurrency transactions snapshot isolation-level

我有一个从多个线程调用的进程,它执行以下操作:

  1. 开始交易
  2. 使用提示(UPDLOCK,HOLDLOCK,READPAST)查找IsProcessed = 0的下一行,从工作表中选择工作单元
  3. 处理工作单元(C#和SQL存储过程)
  4. 提交交易
  5. 这个想法是一个线程进入池中进行“下一步”工作,并对其进行处理,并且锁定在那里以确保单个工作不会被处理两次。 (顺序无关紧要)。

    所有这些都已经好几个月了。直到今天,当我碰巧意识到尽管启用了快照隔离并使其成为数据库级别的默认值时,实际的事务创建代码却手动设置了“ReadCommitted”的隔离级别。

    我正式将其更改为“Snapshot”,当然立即收到“您只能在READ COMMITTED或REPEATABLE READ中指定READPAST锁定”错误消息。糟糕!

    锁定行的主要原因是“标记行”,以便在提交应用标记的事务时删除“标记”并且锁定似乎是执行此操作的最佳方法,因为除了这些线程之外,不会读取此表。如果我使用IsProcessed标志作为锁,那么我可能需要先进行更新,然后选择刚刚更新的行,但我需要使用NOLOCK标志来知道是否有其他线程设置了在一排上的旗帜。

    所有听起来都有点乱。最简单的选择是完全放弃快照隔离模式,但步骤#3的设计需要它。

    关于解决此问题的最佳方法有什么好主意吗?

    由于

    马库斯

1 个答案:

答案 0 :(得分:1)

将特定事务的隔离级别更改为默认读取提交之外的其他级别(在您的情况下,您已默认在快照模式下执行操作)。然后,您可以在快照中将其他工作留在数据库中,但代码中的此特定工作流将不是快照。