我在我的应用程序中遇到此幻像问题,其中特定页面(在ASP.NET MVC应用程序上)每5个请求中就有一个会抛出此错误:
Npgsql.NpgsqlException: ERROR: 57014: canceling statement due to user request
at Npgsql.NpgsqlState.<ProcessBackendResponses>d__0.MoveNext()
at Npgsql.ForwardsOnlyDataReader.GetNextResponseObject(Boolean cleanup)
at Npgsql.ForwardsOnlyDataReader.GetNextRow(Boolean clearPending)
at Npgsql.ForwardsOnlyDataReader.Read()
at Npgsql.NpgsqlCommand.GetReader(CommandBehavior cb)
...
在npgsql github页面上,我发现了以下错误报告:615
它说:
无论Dapper到底发生了什么,都有 肯定是取消命令时的竞争条件。部分原因是 按设计,因为PostgreSQL:完全取消请求 &#34;异步&#34; (他们通过一个不相关的套接字,而不是作为一部分 要取消的连接),你不能限制 取消仅对特定命令生效。其他 单词,如果要在取消时取消命令A. 已发送命令B可能已在进行中,它将是 取而代之的是。
虽然他们已经进行了&#34;更改,希望在Npgsql 3.0.2中使取消更加安全&#34; 我的当前代码与此版本不兼容,因为需要迁移描述{{3 }}
我当前的解决方法(愚蠢):我已经在Dapper中对command.Cancel();
的代码进行了评论,问题似乎已经消失。
if (reader != null)
{
if (!reader.IsClosed && command != null)
{
//command.Cancel();
}
reader.Dispose();
reader = null;
}
这个问题有更好的解决方案吗?其次,我对当前修复失去了什么(除了我每次更新Dapper时都必须记住更改)?
配置: NET45, Npgsql 2.2.5, Postgresql 9.3
答案 0 :(得分:0)
我发现为什么我的代码没有处理读者,导致调用command.Cancel()
。只有在不读取每个QueryMultiple
时才会使用refcursor
方法。
更改代码:
using (var multipleResults = connection.QueryMultiple("schema.getuserbysocialsecurity", new { socialSecurityNumber }))
{
var client = multipleResults.Read<Client>().SingleOrDefault();
if (client != null)
{
client.Address = multipleResults.Read<Address>().Single();
}
return client;
}
要:
using (var multipleResults = connection.QueryMultiple("schema.getuserbysocialsecurity", new { socialSecurityNumber }))
{
var client = multipleResults.Read<Client>().SingleOrDefault();
var address = multipleResults.Read<Address>().SingleOrDefault();
if (client != null)
{
client.Address = address;
}
return client;
}
这解决了问题,现在读者得到了妥善处理,并且未调用command.Cancel()
。
希望这有助于其他任何人!
<强>更新强>
Npgsql能够要求服务器取消正在进行的命令。去做 这个,调用NpgsqlCommand的Cancel方法。注意另一个线程 必须处理请求,因为主线程将被阻塞等待 命令完成。此外,主线程将引发异常作为 用户取消的结果。 (错误代码是57014。)
我还在Dapper github页面上发布了issue。