【问题标题】:Unexpected Optimistic concurrency exception意外的乐观并发异常
【发布时间】:2013-03-27 22:27:34
【问题描述】:

我尝试更新我的对象的一个​​字段,并立即将其保存到数据库中。

using (var ctx = new DataModel(_connectionString))
{
    var MyObject it = ctx.MyObjects.Where(someConstraint).ToList()[0];
    try
    {
        //update check time
        ctx.Refresh(RefreshMode.StoreWins, it); //making sure I have it
        ctx.AcceptAllChanges(); // in case something else modified it - seems unnecessary
        it.TimeProperty= DateTime.UtcNow; //Setting the field
        ctx.DetectChanges(); //seems unnecessary
        ctx.SaveChanges(SaveOptions.AcceptAllChangesAfterSave); //no SaveOptions changed the behavior
    }
    catch (OptimisticConcurrencyException)
    {
        _logger.DebugFormat(workerClassName + ": another worker just updated the LastCheckTime");
    }
    //Do some other work and/or sleep
}

当我在具有 2 个或更多实例的 Azure 模拟器中运行此程序时,我会在此处收到很多 OptimisticConcurrencyExceptions。

我正在尝试刷新对象,更新其中一个字段,然后将这些更改推送到数据库。 但是,乐观并发阻止了我。

注意:乐观并发是在我从未接触过的 TimeStamp 字段上设置的。

为什么会这样,我该如何解决?

【问题讨论】:

    标签: c# dataset optimistic-concurrency


    【解决方案1】:

    这个 try 块中可能有多个线程,在它们都从数据库刷新之后但在它们中的任何一个保存更改之前修改它们自己的同一实体的副本。

    试试这个:

    using (var ctx = new DataModel(_connectionString))
    {
        bool saved = false;
    
        do
        {
            var MyObject it = ctx.MyObjects.Where(someConstraint).ToList()[0];
    
            try
            {
                it.TimeProperty= DateTime.UtcNow; //Setting the field
                ctx.SaveChanges(SaveOptions.AcceptAllChangesAfterSave); 
    
                saved = true;
            }
            catch (OptimisticConcurrencyException)
            {
                _logger.DebugFormat(workerClassName + ": another worker just updated the LastCheckTime");
    
                ctx.Refresh(RefreshMode.StoreWins, it);
                ctx.AcceptAllChanges();
           }
        } while( !saved )
        //Do some other work and/or sleep
    }
    

    如果这对您有用,请更改 while 条件以限制尝试次数。

    【讨论】:

    • 否 - 我有多个进程执行相同的代码,但每个进程都是单线程的
    • 仍然有可能不同的进程同时修改同一个实体。遇到异常后处理刷新
    • 我不太关心刷新 - 我需要将其推送到数据库。在本地,此后不再使用变量“it”。另外-我刚刚检查了调试器:此代码在每个进程的单个线程中运行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    相关资源
    最近更新 更多