"오류 : 57014 : 사용자 요청으로 인해 명령문 취소 중"Npgsql

command dapper npgsql postgresql

문제

내 응용 프로그램에서 특정 페이지 (ASP.NET MVC 응용 프로그램에서)를 5 번 요청할 때마다이 오류가 발생하는 팬텀 (phantom) 문제가 있습니다.

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 때문에 취소 된 요청은 완전히 "비동기 적"(취소되는 연결의 일부가 아닌 관련없는 소켓을 통해 전달됨)이며, 취소를 적용하도록 제한 할 수 없습니다 특정 명령에서만. 즉, 명령 A를 취소하려는 경우, 취소가 전달 될 때까지 명령 B가 이미 진행 중일 수 있으며 대신 취소됩니다.

Npgsql 3.0.2에서 "잘하면 취소를 훨씬 더 안전하게 할 수있는 변경" 을했지만, 현재의 코드는이 버전과 호환되지 않습니다. 여기에서 설명한 마이그레이션이 필요하기 때문입니다.

내 현재 해결 방법 (어리 석음) : 나는 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

수락 된 답변

나는 왜 내 코드가 독자를 처형하지 않았는지, command.Cancel() 을 호출하는 것을 발견했다. 이것은 모든 refcursor 가 읽히지 않을 때 QueryMultiple 메서드에서만 발생합니다.

코드 변경 :

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() 이 호출되지 않습니다.

희망이 다른 사람을 도와주세요!

최신 정보

버전 2.2에 대한 npgsql 문서는 다음과 같이 설명합니다.

Npgsql은 진행중인 명령을 취소하도록 서버에 요청할 수 있습니다. 이렇게하려면 NpgsqlCommand의 Cancel 메서드를 호출하십시오. 주 스레드가 명령 대기를 기다리는 동안 차단되므로 다른 스레드가 요청을 처리해야합니다. 또한 주 스레드는 사용자 취소의 결과로 예외를 발생시킵니다. 오류 코드는 57014입니다.

Dapper github 페이지에 문제 를 게시했습니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow