首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用实体框架解决乐观并发更新问题

用实体框架解决乐观并发更新问题
EN

Stack Overflow用户
提问于 2011-01-15 11:16:08
回答 1查看 3.4K关注 0票数 1

当一个用户更新已经被另一个用户更新的时候,我应该如何解决模拟更新?

第一个用户请求‘类别’实体对象,第二个用户也这样做。

第二个用户更新这个对象,第一个用户更新。

我有字段时间戳字段在数据库中,wa设置为并发模式-固定。

我是这样更新的:

代码语言:javascript
运行
复制
public class CategoriesRepository : BaseCategoryRepository
{

     public  void Update(....)
    {
    try
     {
          Category catToUpdate = (from c in Contentctx.Categories where c.CategoryID == categoryId select c).FirstOrDefault();
          catToUpdate.SectionReference.EntityKey = new System.Data.EntityKey("ContentModel.Sections", "SectionID", sectionId);

          if (catToUpdate != null)
          {
               //Set fields here....
              Contentctx.SaveChanges();
          }

          base.PurgeCacheItems(CacheKey);
    }

    catch (OptimisticConcurrencyException ex)
    {

             }
    }

}
//Contentctx comes from base class: Contentctx:  
private ContentModel _contenttx;
        public ContentModel Contentctx
        {
            get
            {
                if ((_contenttx == null))
                {                   
                    _contenttx = new ContentModel();
                }

                return _contenttx;
            }
            set { _contenttx = value; }
        }



//on Business layer:
using (CategoriesRepository categoriesRepository = new CategoriesRepository())
{
            categoriesRepository.UpdateCategory(.....);
}

例外从不跳跃..。

我该怎么处理呢?

EN

回答 1

Stack Overflow用户

发布于 2011-01-15 13:13:02

您确定按您描述的那样执行调用顺序吗?无论如何,这里的主要问题是您不应该使用Upate方法中的查询返回的时间戳。当用户获得用于更新的初始数据时,您应该使用收到的时间戳。它应该是:

processin

  • Update
  • 用户请求来自update的数据-所有字段和时间戳都从DB接收到,
  • 时间戳存储在客户端( web应用程序中的隐藏字段)
  • 用户修改数据和按保存按钮-所有数据,包括旧时间戳被发送到加载当前实体
  • 的方法,所有更新的字段都与旧实体合并。实体的时间戳设置为在第一个step.
  • SaveChanges中接收的时间戳称为

这是因为它可以在第一次调用和更新方法调用之间传递大量时间,因此可能已经处理了几个更改。您必须使用初始时间戳以避免无声地覆盖其他更改。

编辑:

代码语言:javascript
运行
复制
// You are updating category - update probably means that you had to load category
// first from database to show actual values. When you loaded the category it had some 
// timestamp value. If you don't use that value, any change between that load and c
// calling this method will be silently overwritten.
public void Update(Category category)     
{     
    try      
    {           
        Category catToUpdate = (from c in Contentctx.Categories where c.CategoryID == categoryId select c).FirstOrDefault();           
        ...           

        // Now categoryToUpdate contains actual timestamp. But it is timestamp of
        // actual values loaded now. So if you use this timestamp to deal with 
        // concurrency, it will only fire exception if somebody modifies data 
        // before you call SaveChanges few lines of code bellow.

        if (catToUpdate != null)           
        {                
            //Set fields here....  

            // To ensure concurrency check from your initial load, you must 
            // use the initial timestamp.           
            catToUpdate.Timestamp = category.Timestamp;
            Contentctx.SaveChanges();           
        }

        ...
    }      
    catch (OptimisticConcurrencyException ex)     
    {               
        ...
    }     
} 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4699252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档