我们有一个围绕 NHibernate 和 Npgsql 提供程序构建的 Web 应用程序,它在 server 2008 R2 和 .NET 4 上运行良好。我们现在已经升级到 Server 2012 和 4.5 堆栈,并且在数据库层遇到了奇怪的挂起.
我们的线程将在我的测试服务器(服务器 2012 的虚拟实例)上永远冻结,并且在生产服务器上挂起大约 7.5 或 15 分钟(大约 450 秒或 900 秒)(我只知道这一点,因为它通常会告诉在日志中)。
当我设法在我的测试服务上重现它并附加调试器时,我看到一个线程将处于以下状态:
[Managed to Native Transition]
System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode)
System.dll!System.Net.Sockets.NetworkStream.Read(byte[] buffer, int offset, int size)
mscorlib.dll!System.IO.BufferedStream.ReadByte()
Npgsql.dll!Npgsql.NpgsqlState.ProcessBackendResponses_Ver_3.MoveNext()
Npgsql.dll!Npgsql.ForwardsOnlyDataReader.GetNextResponseObject()
Npgsql.dll!Npgsql.ForwardsOnlyDataReader.GetNextRowDescription()
Npgsql.dll!Npgsql.ForwardsOnlyDataReader.NextResult()
Npgsql.dll!Npgsql.ForwardsOnlyDataReader.ForwardsOnlyDataReader(System.Collections.Generic.IEnumerable<Npgsql.IServerResponseObject> dataEnumeration, System.Data.CommandBehavior behavior, Npgsql.NpgsqlCommand command, Npgsql.NpgsqlConnector.NotificationThreadBlock threadBlock, bool synchOnReadError)
Npgsql.dll!Npgsql.NpgsqlCommand.GetReader(System.Data.CommandBehavior cb)
Npgsql.dll!Npgsql.NpgsqlCommand.ExecuteBlind()
Npgsql.dll!Npgsql.NpgsqlTransaction.Rollback()
NHibernate.dll!NHibernate.Transaction.AdoTransaction.Rollback()
在 postgres 端,我还看到了一个正在运行的查询,但我猜那是因为事务永远不会回滚。我们正在使用 Npgsql v2.0.12(最新稳定版)。
这个挂起的原因是什么,以及这个非常长的超时(或测试中没有超时)?为什么它在不同的操作系统上会有所不同?
我们之前确实在一台服务器上使用 .NET 4.5 在服务器 2008 R2 上运行过它,但也从未见过这种行为。但我假设因为这是一个本地调用,它依赖于操作系统?
有没有人有任何理论来解释为什么会发生这种情况?