//未进行并发处理 User user = new User { UserName="shenwei" ,certID= "11111"}; using (BlogContext ctx= new BlogContext()) { ctx.Users.Add(user); ctx.SaveChanges(); } //首先插入一条数据 并提交 //定义两个context同时进行操作 BlogContext firContext = new BlogContext (); User u1 = firContext.Users.FirstOrDefault(); BlogContext secContext = new BlogContext (); User u2 = secContext.Users.FirstOrDefault(); u2.UserName = "zhangxiaomao" ; //改变名字 并提交 secContext.SaveChanges(); u1.UserName = "xxxxxx" ; u1.certID = "22222" ; //另一个操作改变certid,也提交 firContext.SaveChanges();
public class Blog { public string ID { get; set; } public string BlogName { get; set; } public string BlogAuthor { get; set; } public virtual List <Post> Posts { get; set ; } //导航属性 public BlogDetails Detail { get; set; } [ Timestamp] public byte [] version { get; set; } }
测试如下
//并发模拟 Blog b = new Blog { ID = "24", BlogName = "Gaea", BlogAuthor = "shenwei", Detail = new BlogDetails { } }; //先通过一个ctx插入数据并提交 using(BlogContext context=new BlogContext()) { context.Blogs.Add(b); context.SaveChanges(); } //创建一个ctx取的第一条数据,修改 但是不提交 BlogContext fircontext = new BlogContext(); Blog firstblog = fircontext.Blogs.FirstOrDefault(); firstblog.BlogName = "哈哈,被改掉了" ; //创建另一个ctx还是取第一条数据,修改并提交 BlogContext secContext = new BlogContext(); Blog secondBlog = secContext.Blogs.FirstOrDefault(); secondBlog.BlogAuthor = "JasonShen"; secContext.SaveChanges(); //这个时候再提交第一个ctx所做的修改 try { //这是后会发现现在的数据,已经和刚进入时发生了变化,故报错 fircontext.SaveChanges(); Console.WriteLine("保存成功" ); } catch(Exception e) { Console.WriteLine("保存失败" ); } Console.ReadKey(); }
使用Reload数据作为解决乐观并发异常的策略之一,除了Reload外,还有其他几种冲突解决策略,这里只讲下常用的Reload
try { //这是后会发现现在的数据,已经和刚进入时发生了变化,故报错 fircontext.SaveChanges(); Console .WriteLine("保存成功" ); } catch (DbUpdateConcurrencyException e) { Console .WriteLine("保存失败" ); Console .WriteLine("Reload" ); e.Entries.Single().Reload(); Console .WriteLine(firstblog.BlogName); //会发现 变成了初始从数据库里加载的数据值 }
public class User { [Key ,DatabaseGenerated (DatabaseGeneratedOption .Identity)] public Guid UserGuid { get; set; } public string UserName { get; set; } [ ConcurrencyCheck ] public string certID { get; set; } }
//针对单个字段 标示的ConcurrencyCheck 的并发 User user = new User { UserName = "shenwei" , certID = "11111" }; using (BlogContext ctx = new BlogContext ()) { ctx.Users.Add(user); ctx.SaveChanges(); } //首先插入一条数据 并提交 //定义两个context同时进行操作 BlogContext firContext = new BlogContext (); User u1 = firContext.Users.FirstOrDefault(); BlogContext secContext = new BlogContext (); User u2 = secContext.Users.FirstOrDefault(); u2.certID= "22222" ; //改变名字 并提交 secContext.SaveChanges(); try { u1.certID = "33333" ; //另一个操作改变certid,也提交 firContext.SaveChanges(); } catch (Exception e) { Console .WriteLine("并发报错" ); }
原文:http://www.cnblogs.com/JasonShenW/p/5085382.html