多线程npgsql应用遇到数据库问题,我每次都可以重现。
对应用程序运行3个并行登录请求会破坏应用程序的稳定性,然后当我发送批处理(运行多个查询)时,一些ExecuteReader会挂起。
仅当CommandTimeout过期(60秒)时,对command.ExecuteReader()的调用才会返回。
挂起调用中的堆栈跟踪:
[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) Unknown
System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags) Unknown
System.dll!System.Net.Sockets.NetworkStream.Read(byte[] buffer, int offset, int size) Unknown
Npgsql.dll!Npgsql.NpgsqlReadBuffer.Ensure.__EnsureLong|0() Line 150 C#
Npgsql.dll!Npgsql.NpgsqlReadBuffer.Ensure(int count, bool async, bool dontBreakOnTimeouts) Line 116 C#
Npgsql.dll!Npgsql.NpgsqlConnector.ReadMessage.__ReadMessageLong|0(Npgsql.DataRowLoadingMode dataRowLoadingMode2, bool readingNotifications2, bool isReadingPrependedMessage) Line 954 C#
Npgsql.dll!Npgsql.NpgsqlConnector.ReadMessage(bool async, Npgsql.DataRowLoadingMode dataRowLoadingMode, bool readingNotifications) Line 923 C#
Npgsql.dll!Npgsql.NpgsqlDataReader.NextResult(bool async, bool isConsuming) Line 444 C#
[Resuming Async Method]
mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<bool>.Start<Npgsql.NpgsqlDataReader.<NextResult>d__46>(ref Npgsql.NpgsqlDataReader.<NextResult>d__46 stateMachine) Unknown
Npgsql.dll!Npgsql.NpgsqlDataReader.NextResult() Line 332 C#
Npgsql.dll!Npgsql.NpgsqlCommand.ExecuteDbDataReader(System.Data.CommandBehavior behavior, bool async, System.Threading.CancellationToken cancellationToken) Line 1218 C#
Npgsql.dll!Npgsql.NpgsqlCommand.ExecuteDbDataReader(System.Data.CommandBehavior behavior) Line 1130 C#
Npgsql.dll!Npgsql.NpgsqlCommand.ExecuteReader(System.Data.CommandBehavior behavior) Line 1111 C#
> xyz.PostgresDBConnection.ExecReader(Npgsql.NpgsqlCommand comm) Line 279 C#
答案 0 :(得分:0)
这很可能是一个并发问题,其中多个线程同时访问同一连接。
Npgsql带有内置的连接池,就像其他数据库驱动程序一样。假设您尚未禁用此功能,那么建议的做法是每次您要使用数据库时都创建一个新的NpgsqlConnection对象,并在数据库上调用Open()
。完成后,处置连接。不要尝试重用连接对象,因为它的价值很小,并且容易出现并发问题。
答案 1 :(得分:0)
原来的罪魁祸首是以下极其缓慢的查询(在具有31259行的表上):
SELECT Item.id, Item.data FROM Item
INNER JOIN Item AS it ON item.id = Item.id AND item.data = Item.data
AND item.data2 <> Item.data2 LIMIT 1
但是,Npgsql并没有停留在该查询上,而是与之不同,但原因是此查询。
我用其他等效查询替换了它:
SELECT Item.id, Item.data FROM Item
GROUP BY Item.id, Item.data
HAVING COUNT(DISTINCT Item.data2) > 1
LIMIT 1
问题似乎已解决。