前言
最近在做一个web项目,需要用到导出功能,但是由于导出的数据量太大,导致导出的时间太长,所以就想到了一个异步导出的功能,就是用户请求导出,接口先在数据库生成一条用户导出任务的记录状态为未生成,并且开始创建一个异步任务执行生成所需的excel表并且在生成完成后将导出任务的记录状态为已生成,接口返回成功。流程就是用户请求过来接口先生成一条导出任务记录,让后创建了一个异步任务,不用等异步任务完成接口直接返回成功,等异步任务里的文件生成成功后再把记录状态改为生成成功。用户看见文件生成成功后点击下载。
问题
在做上面一个需求的时候遇到一个问题就是,当我生成用户导出记录,开启并执行生成表文件的异步任务后发现无法将用户导出记录修改。但是程序也没有报错。按照正常来说我的异步任务里包含了两个步骤1、生成导出的文件。2、修改数据库将记录状态改为成功。但是异步任务里只执行成功了第一步文件生成成功了但是数据没有修改。
解决
其实这是一个生命周期的问题因为项目是用.NET6做的用了依赖注入在.NET6中这种依赖注入方式创建的dbcontext实例生命周期是整个请求过程。
相当于我异步任务虽然在执行,但是因为我接口已经响应返回了所以dbcontext的生命周期跟着结束了到后面异步任务里再调用dbcontext实例的时候就已经没用了。所以解决方法就是在异步任务里我们要用自己创建的dbcontext实例进行操作,在这里我用了 官方提供的 ContextFactory 实现;
首先我们先将我们的数据库像下面这样注入到ContextFactory中
然后我们在方法里用ContextFactory创建一个dbcontext实例 注意,这种方式创建的DbContext实例需要自己来释放 ,因此建议用using使用
创建方法如下
然后在你的异步任务中用ContextFactory实例来创建一个dbcontext实例,用此实例执行你的数据库操作就行了。