Quando um usuário aborta sua solicitação no meio do processo, às vezes cancelo quaisquer instruções somente leitura que suportem qualquer operação somente leitura que ele estava tentando no momento - sigo esse padrão com moderação - reservado apenas para consultas caras que também ocorrem durante períodos de alto tráfego portanto, tendo o potencial de causar contenção.
No PG, cancelo consultas assim:
SELECT pg_cancel_backend(pid)
;
Quando faço isso, o PG obedece, mas registra isto: Error: canceling statement due to user request
.
Entendo por que seu irmão pg_terminate_backend
se classificaria como um erro; é uma última tentativa potencialmente perigosa que mata o processo à força.
Mas não entendo por que o cancelamento de uma consulta normal é tratado da mesma forma. Afinal, solicitei o cancelamento, então por que ele foi registrado com um nível de severidade tão alto?
De acordo com o padrão SQL, o mecanismo de banco de dados deve comunicar, através da variável SQLSTATE, a condição de cada comando concluído, e o valor de SQLSTATE indica precisamente como o comando foi concluído. O padrão classifica os valores SQLSTATE em classes; um código de cada grupo pode e será tratado de forma diferente pelo cliente.
À condição específica em questão, “query_cancelled”, é atribuído o código 57014, que pertence à classe “errors”. Apropriadamente, quando
psql
vê SQLSTATE 57014 em resposta ao seu comando, ele trata isso como um erro, imprimindo uma mensagem adequada.Você está obtendo esse comportamento porque, do ponto de vista do programa cliente que iniciou a consulta SELECT, o cancelamento dela é um erro.
Por padrão, não está claro se o usuário que iniciou o SELECT (ou qualquer outro comando) foi quem executou a
pg_cancel_backend
chamada. Poderia ter sido um usuário diferente (com a mesma conta sem privilégios) ou um superusuário. Suponha que eu, como DBA, cancele sua consulta sem você saber ou concordar; você certamente gostaria de receber uma mensagem de erro comovente sobre isso, e não apenas um pequeno aviso no canto da janela de que houve 0 resultados ou algo parecido.Conceitualmente, qual seria o resultado se um erro não fosse relatado? O cliente esperaria então algum conjunto de resultados - um número de registros ou um conjunto vazio. Ambos seriam valores de retorno errados - eles sugeririam que houve algum resultado que não existe. Além disso, é claro, se for um programa real, do lado do cliente (e não uma sessão de usuário em alguma ferramenta SQL), você certamente desejaria iniciar qualquer processamento de exceção normalmente, para permanecer consistente.