锁定并发数据库更新的实体框架代码

时间:2013-10-03 08:40:37

标签: c# .net entity-framework parallel-processing entity-framework-5

我有属性State,当设置时,它会更新数据库中的实体。

问题是此属性跨多个线程设置,有时作业字段会同时附加到两个上下文,导致以下异常:

  

实体对象不能被多个实例引用   IEntityChangeTracker。

我试图在using语句周围使用锁,但这不起作用:

private Job job;

public string State 
{
    get
    {
        return job.State;
    }
    set
    {
        lock (job)
        {
            using (MyEntities context = new MyEntities())
            {
                context.Jobs.Attach(job);
                job.State = value;

                context.SaveChanges();
            }
        }
    }
}

最好的方法是什么?

2 个答案:

答案 0 :(得分:1)

如果您可以分离对象而后面没有任何内容,则可以在保存后将其从上下文中分离出来:

lock (job)
{
     using (MyEntities context = new MyEntities())
     {
           context.Jobs.Attach(job);
           job.State = value;
           context.SaveChanges();
           context.Detach(job);  // Detach the object
      }
}

<强>更新

我已经测试了类似的场景,我发现没有问题。我怀疑实体job在进入临界区之前附加到某些上下文。如果job有某些关系,您可以通过http://blogs.msdn.com/b/alexj/archive/2009/06/08/tip-24-how-to-get-the-objectcontext-from-an-entity.aspx

中建议的方式检查某个实体是否附加到某个上下文

答案 1 :(得分:0)

问题是锁定job无效。我不知道为什么。

实现专用锁object非常有效:

private Job job;

private static object jobInstanceLock;

public string State 
{
    get
    {
        return job.State;
    }
    set
    {
        lock (jobInstanceLock)
        {
            using (MyEntities context = new MyEntities())
            {
                context.Jobs.Attach(job);
                job.State = value;

                context.SaveChanges();
            }
        }
    }
}