asp.net core ef core mysql 新增数据并发异常处理

net core 2.0发布后,一直想体验下,因种种原因,一直在拖着没进行。

前阵子公司要加个新的内部管理后台,正好可以用asp.net core来做下,体验下net core的魅力。

啃过文档后就上手了,一切很顺利。

直到周五,出现了一个并发异常的问题,本以为可以很快处理掉的,但没想到一直花费了很长时间才解决掉,现在记录下情况,有相同经历的伙伴以后可以参考。

先上异常截图。

异常提示:

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See

http://go.microsoft.com/fwlink/?LinkId=527962

for information on understanding and handling optimistic concurrency exceptions.

再上代码

 public int Add(BannerView bannerView)
        {
            try
            {

                //sysBanner.ImgUrl = sysBanner.ImgUrl.Contains("http") ? sysBanner.ImgUrl : _programConfig.AliYunOSSUrl + sysBanner.ImgUrl;
                //sysBanner.CreateDate = DateTime.Now;
                _banner.Add(new SysBanner {
                    Content = bannerView.Content,
                    CreateDate = DateTime.Now,
                    Del = (int)bannerView.Del,
                    ImgUrl = bannerView.ImgUrl.Contains("http") ? bannerView.ImgUrl : _programConfig.AliYunOSSUrl + bannerView.ImgUrl,
                    Operation = "",
                    Sort = bannerView.Sort,
                    SrcUrl = bannerView.SrcUrl,
                    Title = bannerView.Title,
                    Type = (int)bannerView.Type,
                    //MaterialId = 0,
                    //Parameter = 0,
                    //ShareType = 0
                });
                return  _banner.SaveChanges();

            }
            catch (DBConcurrencyException ex)
            {
                throw;
            }
        }

  

        /// <summary>
        /// 新增一条数据
        /// </summary>
        /// <param name="model"></param>
        public void Add(TEntity model)
        {
            var entity=_dbSet.Add(model);
        }

       public int SaveChanges()
        {
            return _dbContext.SaveChanges();
        }        

代码特别简单,就是新增一条数据,进行保存,完全没复杂的东西。

出现并发异常,整个人是蒙逼状态。

单人进行调试,新增一条数据,自增ID,不存在多用户同时操作,怎么可能出现并发?

即使出现并发,主键也是自增ID,只会出现多条数据,也不可能是并发异常……并且多个业务模块,其他模块的新增完全是正常的。

这又是为什么!!!!

首先就是审视代码,确定没问题……检查依赖注入,没有问题……检查ef生成的sql,没有问题……阅读官方文档,没找到原因……去群里向各位朋友请教,还是无法解决。

官方文档有一个DBConcurrencyException处理并发异常的,是基于修改和更新的,经试验,无法解决。

一步一步调试,源码调试,找到几处疑点,经排查都不是引起新增并发的bug。

重新dbfrist生成model实体,无法解决……删除表,重建表,无法解决。

似乎走进了死胡同,园子里博问发贴,也没有解决。整个排除过程,说起来都是泪。

后来就在想,既然底层调用方法都是一样的,那唯一不一样的就是存储的实体,会不会是表结构导致的?

经过对比出现异常的表与正常的表结构,发现一个不同点,里面有几个字段设置了默认值,还有两个非null字段,而正常操作的那些实体里是没有的。

尝试取消默认值后,再注释掉dbFirst生成的一行代码HasDefaultValueSql("xxx"),再一运行,居然成功了!!!

难道是ef core mysql的bug?表不能设置默认值?这似乎不合道理,产品发布这么久了,很多人已经用在生产环境了,不可能出现这么低级的错误吧?

在园子里博问发贴时,有位园友向我说,默认值的字段,要加.HasDefaultValue()。这种是code first时加的,而我用dbFirst时自动生成的是HasDefaultValueSql("xxx")。

难道是调用函数不同而产生的bug?

经过多次实际测试,数据库设置默认值及非null字段是没有问题的。

问题出在db first生成实体时时自动加的这行代码上HasDefaultValueSql("xxx"),只需要注释掉这些代码,运行就正常。

.HasDefaultValue()一样会引起新增并发异常,原因未知。

asp.net core 2.0

ef core mysql

pomelo.entityFrameworkCore.mySql

如果有朋友遇到类似问题,可以做为参考。

至于为什么不能用HasDefaultValueSql("xxx")及.HasDefaultValue(),目前正在研究中,有新发现,会更新文章。

时间: 2024-11-15 21:41:40

asp.net core ef core mysql 新增数据并发异常处理的相关文章

asp.net core+ef core

asp.net core+ef core 官方的文档https://docs.asp.net/en/latest/tutorials/first-mvc-app/start-mvc.html 先来看一下实现的效果 开始之前,确定本机已经有.NET Core环境.https://www.microsoft.com/net/core#windows 1.创建解决方案的文件结构如下图(模糊处理的过文件是自己后面加的和ef生成的). 2.要使用ef core,先引用ef core相关的程序包.https

.net core EF Core 视图的应用

由之前的一篇文章<.net core Entity Framework 与 EF Core>我们都已经知道 EF Core 增加了许多特性,并且性能上也有了很大的提升. 但是EF Core是不支持存储过程及视图的映射的,那么直接通过 DbContext 是没有办法直接调用(就是不能直接 "点" 出来)到存储过程与视图的. 上一篇<.net core EF Core 调用存储过程>中已经讲到了存储过程的调用了,这篇就只讲视图了. 对视图来讲,在数据库中 EF Co

EF Core下利用Mysql进行数据存储在并发访问下的数据同步问题

小故事 在开始讲这篇文章之前,我们来说一个小故事,纯素虚构(真实的存钱逻辑并非如此) 小刘发工资后,赶忙拿着现金去银行,准备把钱存起来,而与此同时,小刘的老婆刘嫂知道小刘的品性,知道他发工资的日子,也知道他喜欢一发工资就去银行存起来,担心小刘卡里存的钱太多拿去"大宝剑",于是,也去了银行,想趁着小刘把钱存进去后就把钱给取出来,省的夜长梦多. 小刘与刘嫂取得是两家不同的银行的ATM,所以两人没有碰面. 小刘插入银行卡存钱之前查询了自己的余额,ATM这样显示的: 与次同时,刘嫂也通过卡号和

在vs2015上使用asp.net core+ef core

官方的文档https://docs.asp.net/en/latest/tutorials/first-mvc-app/start-mvc.html 先来看一下实现的效果 开始之前,确定本机已经有.NET Core环境.https://www.microsoft.com/net/core#windows 1.创建解决方案的文件结构如下图(模糊处理的过文件是自己后面加的和ef生成的). 2.要使用ef core,先引用ef core相关的程序包.https://docs.efproject.net

[.Net Core] EF Core实践(DB First)

一.开发环境: VS2015, .Net Core 1.0.0-preview2-003156 二.准备数据: CREATE DATABASE [Blogging]; GO USE [Blogging]; GO CREATE TABLE [Blog] ( [BlogId] int NOT NULL IDENTITY, [Url] nvarchar(max) NOT NULL, CONSTRAINT [PK_Blog] PRIMARY KEY ([BlogId]) ); GO CREATE TAB

asp.net Core EF core ( Entity Framework 7 ) 数据库更新维护

CreateData-baseIfNotExists等之前的API已经废弃,现在采用的是微软封装好,简化.高效的API,migrations 因为,旧API,要付出高昂的代价,以及局限性 打开VS2017,选择工具->NutGet包管理器->程序包管理器控制台 1.输入Add-Migration MyFirstMigration 指令 就会根据当前的dbcontext自动生成Migrations文件夹及文件,这些文件用于新建.或者扩展专属于Migrations 这个API的扩展的数据库 然后在

vs2017 .net core EF 安装mysql

环境: VS2017 .net core 2.0 问题: 在vs 中nuget管理器中无官方支持mysql版本,官方还未发布正式版本 解决: 在www.nuget.org 下载官方mysql支持的dmr版本 在搜索栏输入,MySql.Data.EntityFrameworkCore 查找官方版本,目前最新是MySql.Data.EntityFrameworkCore 8.0.8 dmr 另外依赖MySql.Data 8.0.8 dmr 安装: 在vs2017 中,选择“工具->Nuget包管理器

MySQL新增数据,存在就更新,不存在就添加

1.插入一条数据,存在就更新,不存在就更新(必须现有唯一键)使用insert ignore语句: insert ignore into table(col1,col2) values ('a','b'); 例如插入数据: insert ignore into user_info (last_name,first_name) values ('LeBron','James'); 这样一来,如果表中已经存在last_name='LeBron'且first_name='James'的数据,就不会插入,

如何使EF Core不插入MySql中自增长的主键(踩坑实录)

公司要求使用 .Net Core + EF Core + Mysql 开发项目,为了以后可以部署到Linux服务器上,实际是奇葩的客户需求. 数据库设计时虽然大部分表的主键都采用了UUID(也就是SQL Server的GUID),好处是啥我也就不(bu)说(hui)了(shuo),大家自行百度下吧. 而对于一些不是那么重要的表,或者说会经常产生大量数据的表,我们都是用自增长的主键,然后重点来了,在使用“Scaffold”命令生成实体类的时候,是下面这样的: public partial clas