EF并发异常处理

Posted cxxtreasure

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
        1608036799
        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、更新并发异常捕获处理

以上是关于EF并发异常处理的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用标识列添加新条目时,EF6 引发并发异常

异常和TCP通讯

EF、ASP MVC + 依赖注入。多个并发请求和数据库连接的问题

如何优雅地处理 EF Core 异常

EF DbContext 并发执行时可能出现的问题

EF异常:“System.InvalidOperationException”类型的未经处理的异常在 mscorlib.dll 中发生