首页 新闻 赞助 找找看

asp.net core ef core 新增加一条数据出现并发错误。【肯请指个解决问题的方向】

0
悬赏园豆:100 [已关闭问题] 关闭于 2017-12-10 15:29

前提:

一、新项目,单机测试,已经去掉了其他无关的东西,目前是单一一个页面做新增【理论上不会出现并发,不会有多个修改同一数据的问题】,打开工具fildder,也没发现有重复提交。

二、是新增数据,不是修改更新等等的问题。

三、老数据库新项目,里面并没有加入并发的时间戳等。

【肯请指个解决问题的方向】

代码很简单,没什么复杂 的地方,就是出现了并发。【我自己开发调试,只访问了一个简单的页面做新增……】

Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0]
An unhandled exception has occurred while executing the request
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.
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyException(Int32 commandIndex, Int32 expectedRowsAffected, Int32 rowsAffected)
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithPropagation(Int32 commandIndex, RelationalDataReader reader)
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.Consume(RelationalDataReader reader)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.MySqlBatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IReadOnlyList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at Global_CFP_Admin.Repository.BaseRepository`1.SaveChanges() in D:\Work\Global_CFP_Admin\Global_CFP_Admin.Repository\BaseRepository.cs:line 552
at Global_CFP_Admin.Services.BannerServices.BannerServices.Add(BannerView bannerView) in D:\Work\Global_CFP_Admin\Global_CFP_Admin.Services\BannerServices\BannerServices.cs:line 95
at Global_CFP_Admin.Web.Controllers.BannerController.CreateOrEdit(BannerView bannerView) in D:\Work\Global_CFP_Admin\Global_CFP_Admin.Web\Controllers\BannerController.cs:line 122
at lambda_method(Closure , Object , Object[] )
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeInnerFilterAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeFilterPipelineAsync>d__17.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.<InvokeAsync>d__15.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()

风徐徐的主页 风徐徐 | 初学一级 | 园豆:36
提问于:2017-12-09 19:07
< >
分享
所有回答(2)
0

这个只是SaveChanges的返回值为0,并不一定是并发问题,建议检查一下实际执行的SQL语句

dudu | 园豆:31075 (高人七级) | 2017-12-09 19:31

查看过生成的sql,并用sql在数据库执行是成功的。

项目还有多个其他控制器,新增都是正常,唯有这个一直通不过。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-09 21:06

@风徐徐: 有没有什么地方使用了单例?

支持(0) 反对(0) dudu | 园豆:31075 (高人七级) | 2017-12-09 21:57

@dudu: 没有,dbcontext是用asp.net corer的依赖注入,注入方式是scope。仓储和服务也都是scope。明天我发下注入的代码,现在项目没在这边。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 00:17

没有使用单例的,是主要的一点是,有几个其他业务的所有操作都正常,就这个不行,已经尝试过删表重建,还是没效果。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 12:18

对比其他新增的sql,发现这个多了这一句。

其他新增的是没有这个的。

对比代码,除了表实体不一样外,其他全是一样的,新增和保存用的同一个BaseRepository的方法。

现在还是不清楚哪里导致这个多了这么一句。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 14:47

已经解决,有可能是ef core mysql的bug,现在还不确定,晚些做个试验。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 15:25

@风徐徐: 如果有默认字段,需要在配置映射时使用HasDefaultValue

builder.Entity<User>().Property(a => a.DateAdded).HasDefaultValue();
支持(0) 反对(0) dudu | 园豆:31075 (高人七级) | 2017-12-10 17:25

@dudu: 已经测试过了,如果有hasDefaultValue()就会报并发,注释掉反而好了。我是DBFirst的,生成的默认就带的有HasDefaultValue()的,结果一直报并发。

今天排查到取消数据表中的默认字段就正常后,觉得不可能是ef core mysql的bug,比竟这么多人用,不可能没人发现。就又将表中的默认字段加回去了,然后注释了代码中的HasDefaultValue(),就一切正常了。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 17:49

@dudu: 

目前一切正常,新增不会报并发了。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 17:51

@dudu: 哦,两个函数名字似乎有区别,不知道实际调用的是否一样,等下再看看。 我那个是DBfirst生成时,自动生成的,不是手工加上的。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 17:57

@dudu: 经实测,不能加hasDefaultValue(),加后报并发异常。net core 2.0 ,ef core mysql,pomelo.entityFrameworkCore.mySql

支持(1) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 18:30

@风徐徐: 你用的是最新版EF Core吗?

支持(0) 反对(0) dudu | 园豆:31075 (高人七级) | 2017-12-10 20:35

@dudu: 

ef core 2.0.1

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 21:49

上周新建的项目,直接引用的,没有指定版本号。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 21:52

@风徐徐: 我们的项目中用的就是HasDefaultValue,但数据库用的是SQL Server

支持(0) 反对(0) dudu | 园豆:31075 (高人七级) | 2017-12-10 21:58

@dudu: 有空了研究下源码。

目前不知道实个实现机制,据自己感觉。表中有字段可以为Null,但是有默认值。ef追踪到实体,有设置hasDefaultValue()时,由于不知道插入数据后,表中的具体字段值会是什么,有可能会出现实体值与数据库值不一致的现象。

因此多加了段代码,查询这些字段的值返回,要附加给实体上,当数据返回时,向实体个附加,又修改了实体的值,就造成了并发冲突吧。

猜可能是这个原因

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 22:08

@风徐徐: 可为NULL,设置默认值有何用

支持(0) 反对(0) dudu | 园豆:31075 (高人七级) | 2017-12-10 22:11

@dudu: 老项目的数据库,以前其他人建的,已经是这样的,现在新做的后台,我用下asp.net core,没考虑这么多。应该是core的处理机制不一样,有了这个查询再附加值回去实体的操作。老版本的net mvc也是读这个表,没出这样的情况。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 22:24

@dudu: 时间不早了,早些休息!谢谢你,帮我一起看这个问题。

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-10 22:38
0

已经发现问题,表中字段不能设置默认值,现在还不清楚是否是ef core mysql的bug,稍晚做试验验证下。

风徐徐 | 园豆:36 (初学一级) | 2017-12-10 15:27

可否告知详细的解决方案。我也遇到了一样的问题。

支持(0) 反对(0) Bluto | 园豆:317 (菜鸟二级) | 2017-12-22 22:40

@Bluto: 上面不是已经说了么,数据库字段默认值的原因。具体请看http://www.cnblogs.com/fong/p/8017945.html

支持(0) 反对(0) 风徐徐 | 园豆:36 (初学一级) | 2017-12-26 09:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册