登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
轻量养虾,开箱即用!低 Token + 稳定算力,Gitee & 模力方舟联合出品的 PocketClaw 正式开售!点击了解详情
代码拉取完成,页面将自动刷新
开源项目
>
WEB应用开发
>
Web开发框架
&&
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
9.9K
Star
14.5K
Fork
4.2K
GVP
dotNET China
/
Furion
代码
Issues
0
Pull Requests
0
统计
流水线
服务
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
开发画像分析
我知道了,不再自动展开
更新失败,请稍后重试!
移除标识
内容风险标识
本任务被
标识为内容中包含有代码安全 Bug 、隐私泄露等敏感信息,仓库外成员不可访问
Scoped.Create 里执行sql .SqlNonQuery()或者 obj.insert() 问题
已完成
#I3WB5O
yibey
创建于
2021-06-20 11:35
> 特别说明:如果 Issue 报告为问题且开发成员回复确认问题之后但**三天内**都不能得到反馈,则视为无效Issue。 ### Furion 版本号 2.9.3 ----------- ### Web 项目类型 - [x] WebApi - [ ] Mvc - [ ] Razor Pages - [ ] Blazor Server ----------- ### 描述你的问题 我通过messageCenter发布一个事件后,执行了一个方法,方法执行如下方法,其中skus(是实体类的Sku的数组)是事件总线发布的参数 Scoped.Create((_, scope) => { var services = scope.ServiceProvider; var service = (ISkuService)services.GetService(typeof(ISkuService)); service.GenerateSkuT(skus); }); 然后再genergeSkuT里边执行了 通过sku数组根据一定的规则生成skuts(实体类SkuT)数组. 最后执行 (1)skuts.ForEach(r=>r.Insert()); (2) sql.SqlNonQuery()//sql是某个语句 然后提交保存 rep.Context.SaveChanges(); 如上执行 如果只执行1,则系统不报错但是数据库没有插入,如果执行了1和2,则2报错如下堆栈 然后通过改变方法。(1) skuts.ForEach(r => { rep.Insert(r); }); (2)rep.Context.Database.ExecuteNonQuery(sql); 然后提交保存 rep.Context.SaveChanges();则提交成功 根据错误提示,和变通代码的成功,猜测可能是数据库上下文串线程和作用域了,可能是主线程里的context执行完被disposed,影响到了另外一个线程的context也被释放了,是不是可以考虑用ThreadLocal线程安全来管理数据库上下文。另外使用Scoped.CreateUow同样会出现别的错误。 ----------- ### 异常堆栈信息 Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'DefaultDbContext'. at MySqlConnector.Core.ServerSession.StartQuerying(ICancellableCommand command) in /_/src/MySqlConnector/Core/ServerSession.cs:line 290 at MySqlConnector.Core.CommandExecutor.<ExecuteReaderAsync>d__0.MoveNext() in /_/src/MySqlConnector/Core/CommandExecutor.cs:line 56 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MySqlConnector.MySqlCommand.<ExecuteNonQueryAsync>d__69.MoveNext() in /_/src/MySqlConnector/MySqlCommand.cs:line 266 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at MySqlConnector.MySqlCommand.ExecuteNonQuery() in /_/src/MySqlConnector/MySqlCommand.cs:line 101 at StackExchange.Profiling.Data.ProfiledDbCommand.ExecuteNonQuery() in C:\projects\dotnet\src\MiniProfiler.Shared\Data\ProfiledDbCommand.cs:line 288 at Furion.DatabaseAccessor.SqlAdoNetExtensions.ExecuteNonQuery(DatabaseFacade databaseFacade, String sql, DbParameter[] parameters, CommandType commandType) at Furion.DatabaseAccessor.PrivateSqlRepository.SqlNonQuery(String sql, DbParameter[] parameters) at Furion.DatabaseAccessor.SqlStringExecutePart.SqlNonQuery(DbParameter[] parameters) at Furion.DatabaseAccessor.Extensions.SqlStringExecuteExtensions.SqlNonQuery(String sql, DbParameter[] parameters) at LL.Refound.Core.Service.SkuService.GenerateSkuT(Object skuso) inService\Sku\SkuService.cs:line 279 at LL.Refound.Core.Service.SkuChangeSubscribeHandler.<>c__DisplayClass3_0.<DealSku>b__0(IServiceScopeFactory _, IServiceScope scope) in xxxx\Service\Sku\Event\SkuChangeSubscribeHandler.cs:line 60 at Furion.DependencyInjection.Scoped.Create(Action`2 handler, IServiceScopeFactory scopeFactory) at LL.Refound.Core.Service.SkuChangeSubscribeHandler.DealSku(Sku[] skus) in xxxx\Service\Sku\Event\SkuChangeSubscribeHandler.cs:line 52 at LL.Refound.Core.Service.SkuChangeSubscribeHandler.CreateSku(String eventId, Object payload) in xxxx\Service\Sku\Event\SkuChangeSubscribeHandler.cs:line 39 at Furion.EventBus.InternalMessageCenter.<>c__DisplayClass7_1.<<Send>b__0>d.MoveNext() ----------- ### 代码或代码仓库 ``` //SkuService:ISkuService public class SkuService : BaseController, ISkuService, ITransient { public IRepository<Sku> _skuRep; // 菜单表仓储 public SkuService (){ //注入rep } [HttpPost("batchCreate")] public async Task batchCreate() { List<Sku> skus = new List<Sku>(); for (var i = 0; i < 3; i++) { var Sku = new Sku() { Id = 3 + i, Cn = "测试" + i, En = "1" }; Sku.Insert(); skus.Add(Sku); } _skuRep.Context.SaveChanges(); Debug.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); MessageCenter.Send("create:Sku", skus.ToArray()); } [NonAction] public void GenerateSkuT(Sku[] skus) { Debug.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); for (var i = 0; i < 2; i++) { var Sku = new SkuT() { Id = i, Cn = "SKUT测试" + i, En = "1" }; _skuRepository.Context.Add<SkuT>(Sku); //Sku.Insert(); } string sql = "update sku set Cn ='sdf' where id =3"; sql.SqlNonQuery(); _skuRepository.Context.SaveChanges(); } } //事件 public class SkuChangeSubscribeHandler : ISubscribeHandler { // 定义一条消息 [SubscribeMessage("create:Sku")] public void CreateSku(string eventId, object payload) { Debug.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); DealSku((Sku[])payload); } public void DealSku(Sku[] skus) { Scoped.Create((_, scope) => { Debug.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); var services = scope.ServiceProvider; var service = (TestService)services.GetService(typeof(TestService)); service.GenerateSkuT(skus); }); } } ``` ----------- ### 数据库信息 - [ ] Sqlite - [ ] SqlServer - [X] Mysql - [ ] Oracle - [ ] PGSql - [ ] Firebird - [ ] Cosmos ----------- ### 期待结果 我的需求是,当用户批量导入数据后,快速提交并相应成功,通过异步事件方法GenerateSkuT去执行其他多余的任务(这个任务可能很繁琐)。 另外针对单个操作A方法,我用UnitOfWork, 我希望在数据提交后再发布事件去执行其他的操作,除了手动提交外有没有其他办法 -----------
> 特别说明:如果 Issue 报告为问题且开发成员回复确认问题之后但**三天内**都不能得到反馈,则视为无效Issue。 ### Furion 版本号 2.9.3 ----------- ### Web 项目类型 - [x] WebApi - [ ] Mvc - [ ] Razor Pages - [ ] Blazor Server ----------- ### 描述你的问题 我通过messageCenter发布一个事件后,执行了一个方法,方法执行如下方法,其中skus(是实体类的Sku的数组)是事件总线发布的参数 Scoped.Create((_, scope) => { var services = scope.ServiceProvider; var service = (ISkuService)services.GetService(typeof(ISkuService)); service.GenerateSkuT(skus); }); 然后再genergeSkuT里边执行了 通过sku数组根据一定的规则生成skuts(实体类SkuT)数组. 最后执行 (1)skuts.ForEach(r=>r.Insert()); (2) sql.SqlNonQuery()//sql是某个语句 然后提交保存 rep.Context.SaveChanges(); 如上执行 如果只执行1,则系统不报错但是数据库没有插入,如果执行了1和2,则2报错如下堆栈 然后通过改变方法。(1) skuts.ForEach(r => { rep.Insert(r); }); (2)rep.Context.Database.ExecuteNonQuery(sql); 然后提交保存 rep.Context.SaveChanges();则提交成功 根据错误提示,和变通代码的成功,猜测可能是数据库上下文串线程和作用域了,可能是主线程里的context执行完被disposed,影响到了另外一个线程的context也被释放了,是不是可以考虑用ThreadLocal线程安全来管理数据库上下文。另外使用Scoped.CreateUow同样会出现别的错误。 ----------- ### 异常堆栈信息 Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances. Object name: 'DefaultDbContext'. at MySqlConnector.Core.ServerSession.StartQuerying(ICancellableCommand command) in /_/src/MySqlConnector/Core/ServerSession.cs:line 290 at MySqlConnector.Core.CommandExecutor.<ExecuteReaderAsync>d__0.MoveNext() in /_/src/MySqlConnector/Core/CommandExecutor.cs:line 56 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MySqlConnector.MySqlCommand.<ExecuteNonQueryAsync>d__69.MoveNext() in /_/src/MySqlConnector/MySqlCommand.cs:line 266 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at MySqlConnector.MySqlCommand.ExecuteNonQuery() in /_/src/MySqlConnector/MySqlCommand.cs:line 101 at StackExchange.Profiling.Data.ProfiledDbCommand.ExecuteNonQuery() in C:\projects\dotnet\src\MiniProfiler.Shared\Data\ProfiledDbCommand.cs:line 288 at Furion.DatabaseAccessor.SqlAdoNetExtensions.ExecuteNonQuery(DatabaseFacade databaseFacade, String sql, DbParameter[] parameters, CommandType commandType) at Furion.DatabaseAccessor.PrivateSqlRepository.SqlNonQuery(String sql, DbParameter[] parameters) at Furion.DatabaseAccessor.SqlStringExecutePart.SqlNonQuery(DbParameter[] parameters) at Furion.DatabaseAccessor.Extensions.SqlStringExecuteExtensions.SqlNonQuery(String sql, DbParameter[] parameters) at LL.Refound.Core.Service.SkuService.GenerateSkuT(Object skuso) inService\Sku\SkuService.cs:line 279 at LL.Refound.Core.Service.SkuChangeSubscribeHandler.<>c__DisplayClass3_0.<DealSku>b__0(IServiceScopeFactory _, IServiceScope scope) in xxxx\Service\Sku\Event\SkuChangeSubscribeHandler.cs:line 60 at Furion.DependencyInjection.Scoped.Create(Action`2 handler, IServiceScopeFactory scopeFactory) at LL.Refound.Core.Service.SkuChangeSubscribeHandler.DealSku(Sku[] skus) in xxxx\Service\Sku\Event\SkuChangeSubscribeHandler.cs:line 52 at LL.Refound.Core.Service.SkuChangeSubscribeHandler.CreateSku(String eventId, Object payload) in xxxx\Service\Sku\Event\SkuChangeSubscribeHandler.cs:line 39 at Furion.EventBus.InternalMessageCenter.<>c__DisplayClass7_1.<<Send>b__0>d.MoveNext() ----------- ### 代码或代码仓库 ``` //SkuService:ISkuService public class SkuService : BaseController, ISkuService, ITransient { public IRepository<Sku> _skuRep; // 菜单表仓储 public SkuService (){ //注入rep } [HttpPost("batchCreate")] public async Task batchCreate() { List<Sku> skus = new List<Sku>(); for (var i = 0; i < 3; i++) { var Sku = new Sku() { Id = 3 + i, Cn = "测试" + i, En = "1" }; Sku.Insert(); skus.Add(Sku); } _skuRep.Context.SaveChanges(); Debug.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); MessageCenter.Send("create:Sku", skus.ToArray()); } [NonAction] public void GenerateSkuT(Sku[] skus) { Debug.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); for (var i = 0; i < 2; i++) { var Sku = new SkuT() { Id = i, Cn = "SKUT测试" + i, En = "1" }; _skuRepository.Context.Add<SkuT>(Sku); //Sku.Insert(); } string sql = "update sku set Cn ='sdf' where id =3"; sql.SqlNonQuery(); _skuRepository.Context.SaveChanges(); } } //事件 public class SkuChangeSubscribeHandler : ISubscribeHandler { // 定义一条消息 [SubscribeMessage("create:Sku")] public void CreateSku(string eventId, object payload) { Debug.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); DealSku((Sku[])payload); } public void DealSku(Sku[] skus) { Scoped.Create((_, scope) => { Debug.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); var services = scope.ServiceProvider; var service = (TestService)services.GetService(typeof(TestService)); service.GenerateSkuT(skus); }); } } ``` ----------- ### 数据库信息 - [ ] Sqlite - [ ] SqlServer - [X] Mysql - [ ] Oracle - [ ] PGSql - [ ] Firebird - [ ] Cosmos ----------- ### 期待结果 我的需求是,当用户批量导入数据后,快速提交并相应成功,通过异步事件方法GenerateSkuT去执行其他多余的任务(这个任务可能很繁琐)。 另外针对单个操作A方法,我用UnitOfWork, 我希望在数据提交后再发布事件去执行其他的操作,除了手动提交外有没有其他办法 -----------
评论 (
14
)
登录
后才可以发表评论
状态
已完成
待办的
进行中
已完成
已关闭
负责人
未设置
百小僧
monksoul
负责人
协作者
+负责人
+协作者
标签
疑问
未设置
标签管理
里程碑
Furion 2021
未关联里程碑
Pull Requests
未关联
未关联
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
未关联
分支 (
-
)
标签 (
-
)
开始日期   -   截止日期
-
置顶选项
不置顶
置顶等级:高
置顶等级:中
置顶等级:低
优先级
不指定
严重
主要
次要
不重要
参与者(2)
C#
1
https://gitee.com/dotnetchina/Furion.git
git@gitee.com:dotnetchina/Furion.git
dotnetchina
Furion
Furion
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册