zoukankan      html  css  js  c++  java
  • EF并发异常处理

    场景:投票点赞 在更新总条数字段时  EF先读取model 再进行更新的情景  容易出现并发问题

    可参考文档:

    https://docs.microsoft.com/zh-cn/ef/ef6/saving/concurrency?redirectedfrom=MSDN
    https://www.cnblogs.com/JasonShenW/archive/2015/12/29/5085382.html
    针对整条记录的并发
    EF实现并发控制 需要借助 TimeStamp 标示 ,并且一个类只能有 一个此标示,标示的必须是byte[]类型

    直接上代码:

     [Table("SYS_EMP")]
        public class Emp
        {
            [Key]
            public int Id { get; set; }
            [Column("EMP_CODE")]
            public string EmpCode { get; set; }
            public string NAME { get; set; }
            public string USRID { get; set; }
            public int NUM { get; set; }
            [Timestamp]
            public byte[] version { get; set; }
        }
            /// <summary>
            /// 处理并发冲突(点赞场景)
            /// https://docs.microsoft.com/zh-cn/ef/ef6/saving/concurrency?redirectedfrom=MSDN
            /// </summary>
            public void UpdateEmp()
            {
                EmpDbContext Context1 = new EmpDbContext();
                var emp= Context1.Emp.Where(x=>x.EmpCode == "001").FirstOrDefault();
                emp.NUM += 1;
                Context1.Entry<Emp>(emp).State = System.Data.Entity.EntityState.Modified;
                Context1.Emp.AddOrUpdate(emp);
    
                EmpDbContext Context2 = new EmpDbContext();
                var emp2 = Context2.Emp.Where(x => x.EmpCode == "001").FirstOrDefault();
                emp2.NUM += 1;
                Context2.Entry<Emp>(emp2).State = System.Data.Entity.EntityState.Modified;
                Context2.Emp.AddOrUpdate(emp2);
                int aa = Context2.SaveChanges();
    
                bool saveFailed;
                do
                {
                    saveFailed = false;
                    try
                    {
                        Context1.SaveChanges();
                    }
                    catch (DbUpdateConcurrencyException ex)
                    {
                        saveFailed = true;
                        ex.Entries.Single().Reload();
                        var entry = ex.Entries.Single();
                        var databaseValues = entry.GetDatabaseValues();
                        databaseValues["NUM"]=databaseValues["NUM"] == null ? 1 : (int)databaseValues["NUM"]+1;
                        entry.CurrentValues.SetValues(databaseValues);
                    }
                } while (saveFailed);
            }

     总结:

    1、加时间戳

    2、更新并发异常捕获处理

  • 相关阅读:
    ajax封装
    完美运动框架
    表单上传input=file
    面向对象入门
    浅谈javaScript内存
    关于使用iframe的父子页面进行简单的相互传值
    浅谈原生JavaScript的动画和特效
    rem 原理与简介
    移动 web 适配
    jsonp 简单封装
  • 原文地址:https://www.cnblogs.com/cxxtreasure/p/13311905.html
Copyright © 2011-2022 走看看