【问题标题】:Lost Update Anomaly in Sql Server Update CommandSql Server 更新命令中丢失更新异常
【发布时间】:2010-01-27 13:13:39
【问题描述】:

我很困惑。

我有一个处于 ReadCommitted 隔离级别的事务。除其他外,我还更新了其中的计数器值,类似于以下内容:

Update tblCount set counter = counter + 1

我的应用程序是一个桌面应用程序,并且此事务恰好经常同时发生。我们最近注意到一个错误,有时计数器值不会更新或丢失。我们还在每次计数器更新时插入一条记录,因此我们确定记录已被插入,但不知何故计数器无法更新。这种情况在 2000 次同时交易中发生一次。

我严重怀疑这是我面临的丢失更新异常,但是如果您查看上面的命令,它只是根据自己的值更新计数器:如果我已经开始了一个事务并且事务已经达到了这个语句,它应该已锁定该行。这不应该导致丢失更新,但它会以某种方式发生。

这个更新命令是分两部分工作的吗?就像首先它读取计数器值(在此期间它没有获得排他锁)然后写入新的计算值(当它确实获得排他锁时)?

请帮忙,我真的很困惑。

【问题讨论】:

  • 您是在事务本身中运行它吗?不管你期望它读取什么数据,如果它不在事务中,它也不会锁定任何东西。
  • 没有 WHERE 子句? 2000 个事务都试图更新同一行,但无法扩展。
  • 是的,这是在具有 ReadCommitted 隔离级别的 .NET 事务中,是的,它在查询中有一个 where 子句,如下所示,更新 tblCount set counter = counter + 1 where counterID = 10
  • 您是否尝试过运行 Trace 以查看正在执行的查询?
  • Update tblCount set counter = counter + 1 where counterID = 10Update tblCount set counter = counter + 1 where counter = 10 ?这对任何答案都有很大的影响......

标签: sql-server concurrency transactions


【解决方案1】:

更新命令不能分两部分工作。它只适用于一个。

还有其他事情发生,我的第一个猜测是您的事务正在回滚是出于其他原因。例如,在这 2,000 个事务中,有一个事务可能正在回滚——尤其是当您同时执行大量事务时——它根本没有成功。

该更新也可能不是导致问题的原因 - 您可能由于其他事务而涉及死锁,并且它们可能在更新命令之前(或在更新命令期间)失败。

我会缩小并询问有关事务错误处理的问题。您是否在 try/catch 块中做所有事情?您是否在事务失败时捕获错误级别?如果没有,您需要使用 Profiler 捕获跟踪以了解发生了什么。

【讨论】:

    【解决方案2】:

    你确定 SQL 总是成功的吗?我的意思是,会不会是偶尔的锁定超时?您是否以能够感知它们的方式处理 .Net 代码中的 SQL 异常(即弹出消息或日志条目)?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多