简体   繁体   English

意外的乐观并发异常

[英]Unexpected Optimistic concurrency exception

I try to update a field of my object, and save it right away to the database. 我尝试更新对象的字段,并将其立即保存到数据库中。

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
}

When I run this in Azure emulator with 2 instances or more, I get a lot of OptimisticConcurrencyExceptions here. 当我在具有2个或更多实例的Azure模拟器中运行此代码时,在这里会出现很多OptimisticConcurrencyExceptions。

I am trying to refresh the object, update one of its fields, then push those changes to the database. 我正在尝试刷新对象,更新其字段之一,然后将这些更改推送到数据库。 However, Optimistic Concurrency is preventing me. 但是,乐观并发阻止了我。

note: The optimistic concurrency is set on a TimeStamp field which I never touch. 注意:乐观并发是在我从未接触过的TimeStamp字段上设置的。

Why is that, and how can I fix it? 为什么会这样,我该如何解决?

It's possible you have more than one thread inside this try block, modifying their own copies of the same entity after both have refreshed from the DB but before either of them saved their changes. 可能在这个try块中有多个线程,在从数据库中刷新它们但在它们中的任何一个保存更改之前,修改了它们自己的同一实体的副本。

Try this: 尝试这个:

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
}

If this works for you, change the while condition to limit the amount of attempts. 如果这对您有效,请更改while条件以限​​制尝试次数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM