DataContext.Submit使用奇怪的堆栈跟踪更改超时
本文关键字:跟踪 堆栈 超时 Submit DataContext | 更新日期: 2023-09-27 18:24:14
我为期两年的大项目两周前刚刚上线。虽然我们遇到了正常的发射问题,但它非常成功,只是出现了一个奇怪的错误。
这个故事已经改变了;实际项目与电影票无关。
我们的网站允许电影院的员工打印电影票。一旦他们决定了要打印的内容,他们就会转到打印票证网页并单击"打印"。这会将一批数据发送到电影票打印机,几秒钟后,用户的票打印机开始打印电影票。
我们给票编号,并希望确保没有使用重复的号码。代码看起来是这样的:
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%以上的工作提交都很顺利,只有一小部分出现了这个错误,但当他们出现这个错误时,其中几个人在几分钟内就出现了。我倾向于完全归咎于数据库服务器,除了奇怪的堆栈跟踪。有什么见解吗?
如果超时,这看起来像是死锁的竞争条件。尝试增加一些整数值作为票证的唯一ID而不是简单地使用GUID的动机是什么?LINQ to SQL确实通过设置DataContext.Log属性提供了一些有限的日志记录,但我不知道这在您的生产场景中有多有用/可行。