【问题标题】:DataContext.SubmitChanges timeout with strange stack trace带有奇怪堆栈跟踪的 DataContext.SubmitChanges 超时
【发布时间】:2012-02-13 15:31:50
【问题描述】:

我为期两年的大型项目两周前刚刚上线。虽然我们遇到了正常的启动问题,但它非常成功,除了一个奇怪的错误已经引起人们的注意。

这个故事已经改变;实际项目与电影票无关。

我们的网站允许电影院的员工打印电影票。一旦他们决定要打印什么,他们就会进入打印票网页并单击“打印”。这会向电影票打印机发送一批数据,几秒钟后,用户的票打印机开始打印票。

我们为门票编号,并希望确保没有使用重复的编号。执行此操作的代码如下所示:

using (TicketContext context = new TicketContext(ConnectionString)) {

    // call a stored proc that allocates a group of tickets with fancy transaction stuff

    var result = context.GetNextTicketGroup(tickets.Count).FirstOrDefault();
    if (result == null || !result.Column1.HasValue || result.Column1.Value == -1)
        return "There was an error allocating ticket numbers";
    int ticketNumber = result.Column1.Value;

    // Put the ticket numbers in the ticket objects
    int i;
    for (i = 0; i < ticketCount; i++) {
        tickets[i].TicketNumber = ticketNumber + i;
    }
    for (i = 0; i < ticketCount; i++) {
        // Convert the ticket object that we've been working with into 
        // a record that is the kind we have in the database and 
        // put that into the database.  CreateTicket() doesn't do any 
        // database stuff directly.
        DBTicket newticket = CreateTicket(ticket[i]); 
        context.Tickets.InsertOnSubmit(newticket);
    }
    // Each ticket is tied to an Issuance ID - Get a list of IssuanceIDs from the
    // list of tickets and mark them as printed
    var IDs = items.Select(id => id.IssuanceID).Distinct();
    foreach (Guid g in IDs) {
        var Issuance = context.TicketIssuances.Where(ti => ti.ID == g).FirstOrDefault();
        if(Issuance != null) {
            Issuance.Printed = true;
        }
    }

    // Submit the changes to the database
    context.SubmitChanges();

    // Send the printers to the ticket printer via a web service
    using (TicketService.TicketSoapClient ssc = new TicketService.TicketSoapClient()) {
        var a = tickets.ToArray();
        if (ssc.PrintTickets(a) == false)
            return "Error printing.";
    }
}   // LINE 392

现在,不寻常的部分是 context.SubmitChanges() 超时,但堆栈跟踪如下所示:

 [...]  
 at System.Data.Linq.ChangeDirector.StandardChangeDirector.Insert(TrackedObject item)
 at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
 at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
 at Portal.Tickets.PrintTickets.PrintTicketList(List`1 items) in d:\Source\PrintTickets.aspx.cs:line 392
 at Portal.Tickets.PrintTickets.btnPrintTickets_Click(Object sender, EventArgs e) in d:\Source\PrintTickets.aspx.cs:line 236
 at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
 at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

我在上面的代码中调用了第 392 行;请注意,它是在数据上下文超出范围的地方,在超时应该发生之后。

这些小任务肯定不会因为某种僵局或其他原因而超时;我们一次只将数十条记录放入数据库中,服务器并没有承受过多的负载。我们 99% 以上的工作提交都很好,只有一小部分遇到了这个错误,但是当他们这样做时,他们中的几个人在几分钟内就遇到了这个错误。除了奇怪的堆栈跟踪之外,我倾向于完全归咎于数据库服务器。有什么见解吗?

【问题讨论】:

  • 不应该堆栈跟踪指示第 384 行(对 SubmitChanges 的调用)而不是第 392 行,上下文超出范围吗?而当它发生在周五下午时,当时服务器似乎并没有处于高负载状态。
  • 异常是不是很有帮助的“抛出'System.Web.HttpUnhandledException'类型的异常。超时已过期。在操作完成之前超时时间已过或服务器没有响应。”而且我们经常会出现这样的生产错误,我以前从未见过行号不正确。而且这段代码已经有一段时间没有移动行号了。

标签: c# linq-to-sql datacontext


【解决方案1】:

如果有超时,这看起来像是死锁的竞争条件。尝试增加一些整数值作为票证的唯一 ID 而不是简单地使用 GUID 的动机是什么? LINQ-to-SQL 确实通过设置 DataContext.Log 属性提供了一些有限的日志记录,但我不知道这在您的生产场景中会有多大用处/可行性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多