2012-02-13 71 views
1

我這個爲期兩年的大項目剛剛在兩週前上線。雖然我們已經有了正常的啓動問題,但它已經非常成功,除了一個奇怪的錯誤已經發展起來。DataContext.SubmitChanges超時,出現奇怪的堆棧跟蹤

這個故事已經改變;實際的項目與電影票無關。

我們的網站允許電影院的員工打印電影票。一旦他們決定要打印什麼,他們將進入打印票頁面並點擊「打印」。這將一批數據發送到電影票打印機,幾秒鐘後,用戶的票證打印機開始抽出票。

我們爲門票編號,並且要確保沒有重複的號碼被使用。代碼來執行它看起來像這樣:

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以上;請注意,它正處於datacontext超出範圍的地步,在超時應該發生之後。

這些小型工作當然不會超時出現某種僵局或某種東西;我們一次只能將數十條記錄添加到數據庫中,並且服務器沒有處於過載狀態。我們提交的99%以上的作業都很順利,只有很小的一部分出現了這個錯誤,但是當他們這樣做時,其中幾個人在幾分鐘之內擊中了對方。除了奇怪的堆棧跟蹤之外,我傾向於完全責怪數據庫服務器。任何見解?

+0

不應該堆棧跟蹤指示行384(對SubmitChanges的調用)而不是行392,其中上下文超出範圍?當它發生在星期五下午時,服務器當時似乎沒有承受沉重的負載。 – 2012-02-13 16:23:36

+0

異常是不是非常有用的「異常的類型'System.Web.HttpUnhandledException'被拋出 超時過期。操作完成之前超時時間已過或服務器沒有響應。而且我們有這樣的定期生產錯誤,我從來沒有看到過這個生產線號碼。而且該代碼在很長一段時間內沒有移動行號。 – 2012-02-13 17:46:17

回答

0

如果出現超時,這看起來像是死鎖的競爭狀態。試圖增加一些整數值作爲門票的唯一ID而不是簡單地使用GUID的動機是什麼?通過設置DataContext.Log屬性,LINQ-to-SQL確實提供了一些有限的日誌記錄,但我不知道這將在您的生產場景中有多大用處/可行性。