Temos um processo que seleciona um registro de uma tabela de progresso e emite uma atualização nesse registro.
Se não fizermos a seleção, a atualização funcionará o dia todo. Se fizermos a seleção, a atualização expirará.
A consulta select é bastante simples e se parece com:
select fg."alphakey", n."first-name", n."last-name"
from pub.name n
inner join pub."family-guardian" fg
on (fg."name-id" = n."name-id")
where fg."alphakey" = 'somevalue'
Confirmamos que, se a instrução acima não estiver presente, ela funcionará. No entanto, se a instrução acima estiver presente, o UPDATE falhará. A atualização vai contra a tabela de nomes. Infelizmente, não tenho esse código, pois ele é executado por terceiros.
Duas questões:
- Isso é normal para o progresso?
- Qual é a melhor maneira de contornar o problema?
Se leituras sujas não forem um problema neste cenário, você pode tentar a dica de tabela readuncommitted ou nolock..
Usar 4GL
Acho que a melhor maneira de contornar esse problema de bloqueio é usar 4GL (às vezes chamado de ABL). Em 4GL, o comando mágico é NO-LOCK e você o usa após cada cláusula where da tabela. Infelizmente, o 4GL não suporta os nomes de atalho SQL que tornam as junções úteis. Dito isso, a sintaxe EACH ... OF meio que a substitui - se seus índices estiverem definidos corretamente. Caso contrário, apenas remova o OF e coloque sua condição na cláusula where. Apenas esteja preparado para uma execução mais lenta.
Estávamos executando nossas consultas por meio dos drivers Progress OpenEdge ODBC.
O
Default Isolation Level
foi definido no driver para serRead Committed
. Fizemos essa escolha sem perceber que issoSELECT
causava alguns bloqueios de tabela de longa duração, quando tudo o que queríamos era ter certeza de que não estávamos recebendo leituras sujas.Então, tínhamos duas soluções potenciais. A primeira seria modificar todas as nossas consultas para usar
with (nolock)
conforme sugerido por Michael. A segunda foi mudar o driver ODBC paraRead Uncommitted
.Como a configuração do driver era muito mais fácil de gerenciar, seríamos forçados a fazer leituras sujas, não importa o quê, e a única coisa que nosso aplicativo faz é
SELECT
sair desse banco de dados, então nossa escolha foi clara.