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

  • 开始交易
  • 通过查找带有提示的IsProcessed=0的下一行,从工作表中选择工作单元(UPDLOCK, HOLDLOCK, READPAST)
  • 处理工作单元(C#和SQL存储过程)
  • 提交事务

  • 这样的想法是线程将线程浸入池中以进行“下一个”工作,并对其进行处理,并且存在锁以确保单个工作不会被处理两次。 (顺序无关紧要)。

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

    我将其适当地更改为“快照”,并且当然会立即收到以下消息:

    您只能在READ COMMITTED或REPEATABLE READ中指定READPAST锁

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

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

    关于解决此问题的最佳方法的明智建议吗?

    最佳答案

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

    关于sql-server - 无法在快照隔离模式下使用READPAST,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2639112/

    10-11 22:20
    查看更多