我们有一个报告调度程序引擎,它是一个Windows服务,它将从DB中选择计划在一天中的特定时间生成的报告详细信息(查询,参数等),并运行查询以生成报告。
(首先使用MySQL数据库的EF5代码)
这是它的工作原理:
整个过程一直运作到周五早上。我们现在有2份报告,每天上午8:00和上午8:15。除了星期五之外,每天都会生成报告,当我们遇到第2步(调度程序尝试从数据库中选择报告详细信息)的异常时。
我的代码选择报告详细信息如下:
public void RunScheduler(DateTime dateTime)
{
List<ReportScheduler> schedules;
try
{
schedules = _scheduler.PickFromMSMQToExecute();
if (schedules == null || schedules.Count == 0) return;
Parallel.ForEach(schedules, currentSchld =>
{
CreateScheduledReport(currentSchld, dateTime);
});
}
catch (Exception ex)
{
throw ex;
}
}
这会调用一个函数:
private void CreateScheduledReport(ReportScheduler schedule, DateTime dateTime)
{
_logger = new Log4netFactory().Create("ReportSchedulerService");
Stopwatch timer = new Stopwatch();
var schedulerLog = new ReportSchedulerLog
{
SchedulerRequestID = schedule.RequestID,
StartDateTime = dateTime,
Status = "0",
UpdatedOn = DateTime.Now
};
timer.Start();
var startedTime = DateTime.Now;
var saveSuccess = true;
try
{
var report = _reportRepository.GetReportforScheduling(schedule.ReportID);
GenerateReport(report);
}
catch(Exception ex)
{}
}
表“Reports”有一个userId,它有一个对“users”表的外键引用。在try块中,调用GetReportforScheduling,是调用上下文存储库的函数,如:
public Report GetReportforScheduling(int id)
{
Report rpt = new Report();
String level = String.Empty;
try
{
level = "connecting DB if closed";
ReConnectDatabase(context);
level += ",picking the report for Report ID :" + id.ToString();
rpt = context.Reports.Where(t => t.ReportID == id).Include(m => m.User).FirstOrDefault();
level += ",Picked the report successfully";
if (null == rpt) return new Report();
level += ",Fetching the parameters";
rpt.ReportDetails = context.ReportDetails.Where(x => x.ReportId == id).ToList();
rpt.HasDetail = context.ReportParameters.Any(x => x.ReportTemplateParameters.Any(t => t.TemplateId == rpt.TemplateID) && !(x.IsDynamic == "1"));
level += ",Parameters fetched";
}
catch (Exception ex)
{
_logger.Info("Error Level :" + level);
_logger.Error("Error on picking the report / details from the DB :" + ex.Message, ex);
}
return rpt;
}
该行:
rpt = context.Reports.Where(t => t.ReportID == id).Include(m => m.User).FirstOrDefault();
在每个星期五给出问题,如果我们重新启动Windows服务,它也会像例外一样运行。提出的例外是:
2015-12-25 23:59:39,703 [19] ReportScheduler.Service.exe INFO EIS.DataAccess.Repository.ReportRepository GetReportforScheduling - 错误级别:如果关闭,则选择连接数据库 报告编号报告:15
2015-12-25 23:59:39,718 [19] ReportScheduler.Service.exe错误 EIS.DataAccess.Repository.ReportRepository GetReportforScheduling - 从中选择报告/详细信息时出错 DB:执行命令定义时发生错误。看到 细节的内在例外。
EIS.Infrastructure.Logger.EISException:发生错误 在执行命令定义时。查看内部异常 细节。在 System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand,CommandBehavior行为)
在 System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute [TResultType](ObjectContext的 context,ObjectParameterCollection parameterValues)
在 System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClassb.<GetResults>b__a()<br> at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func
1 func,IDbExecutionStrategy executionStrategy,Boolean startLocalTransaction,Boolean releaseConnectionOnSuccess)
在 System.Data.Entity.Core.Objects.ObjectQuery1.<>c__DisplayClassb.<GetResults>b__9()<br> at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func
1 操作)
在 System.Data.Entity.Core.Objects.ObjectQuery1.GetResults(Nullable
1 forMergeOption)
在 System.Data.Entity.Core.Objects.ObjectQuery1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()<br> at System.Lazy
1.CreateValue()
at System.Lazy1.LazyInitValue()<br> at System.Lazy
1.get_Value()
在System.Data.Entity.Internal.LazyEnumerator1.MoveNext()<br> at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1 来源)
在 System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.b__1 [TResult](IEnumerable的1 sequence)<br> at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable
1 查询,表达式queryRoot)
在 System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute [TResult](式 表达) System.Data.Entity.Internal.Linq.DbQueryProvider.Execute [TResult](式 表达) System.Linq.Queryable.FirstOrDefault [TSource](IQueryable`1 source)
在 EIS.DataAccess.Repository.ReportRepository.GetReportforScheduling(的Int32 id)的
这是因为多线程环境还是延迟加载用户的上下文?