Chu*_*ris 6 .net c# t-sql sql-server ado.net
在极少数情况下,进程在执行过程中会冻结ExecuteNonQuery:
cmd.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)
CommandTimeout设置为 0(无超时)并且UPDATE正在执行一个简单的语句。这通常很快,并且该问题平均每周可以重现一次。但当它发生时,整个过程就会完全冻结/挂起。上次重现时,我们使用 ProcDump 获取该特定进程的转储文件,并可以在那里看到该堆栈跟踪。其他 SO 问题之间的唯一区别是前几行(死锁?)
OS Thread Id: 0x4168 (34)
Current frame: ntdll!NtWaitForSingleObject+0xc
ChildEBP RetAddr Caller, Callee
23eed994 7587f699 KERNELBASE!WaitForSingleObjectEx+0x99, calling ntdll!NtWaitForSingleObject
23eeda08 7587f5f2 KERNELBASE!WaitForSingleObject+0x12, calling KERNELBASE!WaitForSingleObjectEx
23eeda1c 5829e5e2 System_Data!Np::ReadSync+0x205, calling KERNELBASE!WaitForSingleObject
23eeda58 58293812 System_Data!SNIReadSync+0x64
23eeda88 5828a795 System_Data!SNIReadSyncOverAsync+0x25, calling System_Data!SNIReadSync
23eedaa4 53ce748e (MethodDesc 5395aa60 +0x46 DomainBoundILStubClass.IL_STUB_PInvoke(SNI_ConnWrapper*, SNI_Packet**, Int32))
23eedac8 53ce748e (MethodDesc 5395aa60 +0x46 DomainBoundILStubClass.IL_STUB_PInvoke(SNI_ConnWrapper*, SNI_Packet**, Int32))
23eedae4 53cf3c57 (MethodDesc 539498d0 +0x53 SNINativeMethodWrapper.SNIReadSyncOverAsync(System.Runtime.InteropServices.SafeHandle, IntPtr ByRef, Int32)), calling 08a34a78
23eedb04 53e00e5e (MethodDesc 5394a534 +0x5e System.Data.SqlClient.TdsParserStateObject.GetTimeoutRemaining()), calling (MethodDesc 53950710 +0 System.Data.SqlClient.TdsParserStaticMethods.GetTimeoutMilliseconds(Int64))
23eedb18 53e027fb (MethodDesc 5394a90c +0x73 System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()), calling (MethodDesc 539498d0 +0 SNINativeMethodWrapper.SNIReadSyncOverAsync(System.Runtime.InteropServices.SafeHandle, IntPtr ByRef, Int32))
23eedb4c 53e02726 (MethodDesc 5394a8f8 +0x6e System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()), calling (MethodDesc 5394a90c +0 System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync())
23eedb5c 53e0181b (MethodDesc 5394a624 +0x63 System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()), calling (MethodDesc 5394a8f8 +0 System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket())
23eedb68 53e019b3 (MethodDesc 5394a660 +0x2b System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte ByRef)), calling (MethodDesc 5394a624 +0 System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer())
23eedb78 53dedda0 (MethodDesc 5394f064 +0x20c System.Data.SqlClient.TdsParser.TryRun(System.Data.SqlClient.RunBehavior, System.Data.SqlClient.SqlCommand, System.Data.SqlClient.SqlDataReader, System.Data.SqlClient.BulkCopySimpleResultSet, System.Data.SqlClient.TdsParserStateObject, Boolean ByRef)), calling (MethodDesc 5394a660 +0 System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte ByRef))
23eedc0c 53d1d4f0 (MethodDesc 538fe598 +0x7c System.Data.SqlClient.SqlCommand.FinishExecuteReader(System.Data.SqlClient.SqlDataReader, System.Data.SqlClient.RunBehavior, System.String, Boolean, Boolean, Boolean)), calling (MethodDesc 5394f064 +0 System.Data.SqlClient.TdsParser.TryRun(System.Data.SqlClient.RunBehavior, System.Data.SqlClient.SqlCommand, System.Data.SqlClient.SqlDataReader, System.Data.SqlClient.BulkCopySimpleResultSet, System.Data.SqlClient.TdsParserStateObject, Boolean ByRef))
23eedc50 53d1d00b (MethodDesc 538fe56c +0xa2f System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(System.Data.CommandBehavior, System.Data.SqlClient.RunBehavior, Boolean, Boolean, Int32, System.Threading.Tasks.Task ByRef, Boolean, Boolean, System.Data.SqlClient.SqlDataReader, Boolean)), calling (MethodDesc 538fe598 +0 System.Data.SqlClient.SqlCommand.FinishExecuteReader(System.Data.SqlClient.SqlDataReader, System.Data.SqlClient.RunBehavior, System.String, Boolean, Boolean, Boolean))
23eedc68 746b59db clr!JIT_Security_Prolog_Framed+0x15c, calling clr!_EH_epilog3
23eedd18 53d1c27d (MethodDesc 538fe53c +0x605 System.Data.SqlClient.SqlCommand.RunExecuteReader(System.Data.CommandBehavior, System.Data.SqlClient.RunBehavior, Boolean, System.String, System.Threading.Tasks.TaskCompletionSource`1<System.Object>, Int32, System.Threading.Tasks.Task ByRef, Boolean ByRef, Boolean, Boolean)), calling 08a34c1c
23eedd40 72017e17 (MethodDesc 71da0878 +0x37 System.Collections.Hashtable.get_Item(System.Object))
23eedda8 53d16fa3 (MethodDesc 538fe22c +0x187 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(System.Threading.Tasks.TaskCompletionSource`1<System.Object>, System.String, Boolean, Int32, Boolean ByRef, Boolean, Boolean)), calling 08a34b9c
23eede04 53d15f98 (MethodDesc 538fe160 +0xd0 System.Data.SqlClient.SqlCommand.ExecuteNonQuery()), calling 08a38678
Run Code Online (Sandbox Code Playgroud)
我也发现了几个关于这个主题的问题,但没有一个答案似乎是合法的。
我认为问题在堆栈跟踪的最后一帧中清楚地表明:WaitForSingleObjectEx
等待,直到指定的对象处于有信号状态、I/O 完成例程或异步过程调用 (APC) 排队到线程中,或者超时间隔已过。
...
如果超时 dwMilliseconds 为 INFINITE,则仅当对象收到信号或 I/O 完成例程或 APC 排队时,该函数才会返回。
...
使用没有超时间隔的等待函数的线程可能会导致系统死锁。
所以,是的,我相信这是一个僵局,我建议永远不要使用无限超时;在多次重试的循环中使用合理的超时值(5 次就足够了),始终在尝试之间等待随机的时间。 请注意,随机等待对于解决死锁非常重要,否则死锁受害者将在相同的时间后恰好面对循环中的下一个项目,并且由于操作可能需要相同的时间,因此它很容易再次成为死锁受害者。
| 归档时间: |
|
| 查看次数: |
1112 次 |
| 最近记录: |