Npgsql C#wcf应用程序挂在command.ExecuteReader()上

时间:2018-12-13 09:45:37

标签: npgsql

多线程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#

2 个答案:

答案 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

问题似乎已解决。

相关问题