Como você testa condições de corrida em um banco de dados?

30

Tento escrever o código do banco de dados para garantir que não esteja sujeito às condições de corrida, para garantir que bloqueie as linhas ou tabelas corretas. Mas sempre me pergunto: meu código está correto? É possível forçar a manifestação de qualquer condição de corrida existente? Quero ter certeza de que, se eles acontecerem em um ambiente de produção, meu aplicativo fará a coisa certa.

Eu geralmente sei exatamente qual consulta simultânea provavelmente causará um problema, mas não tenho idéia de como forçá-las a executar simultaneamente para ver se o comportamento correto acontece (por exemplo, usei o tipo correto de bloqueio), que os erros corretos são jogado, etc.

Nota: Eu uso o PostgreSQL e o Perl, portanto, se isso não puder ser respondido genericamente, provavelmente deve ser repetido.

Atualização: eu preferiria se a solução fosse programática. Dessa forma, eu posso escrever testes automatizados para garantir que não haja regressões.

xenoterracida
fonte
Por "condição de corrida", você quer dizer "impasse"?
Gaius
2
@Gaius ... não que eu acredito que é um possível resultado de algumas condições de corrida
xenoterracide
As condições de corrida do @Gaius em um banco de dados estariam fazendo coisas como descartar uma tabela antes de ser criada ou atualizar uma linha antes de ser inserida. Geralmente eu imagino que ele é tratado pela lógica do aplicativo fora do próprio banco de dados.
Mark D
atualizando uma linha antes de ter sido inserida? isso não causaria um problema de banco de dados. nenhuma condição de corrida seria como buscar uma linha e atualizá-la, mas ter outro usuário atualizá-la após a busca de sua linha, mas antes do processamento da atualização.
Xenoterracide
1
@ MarkD - Não. Existem muitos tipos de condições de corrida resultantes do encapsulamento incorreto de uma unidade atômica de trabalho em seu banco de dados. Aqui está um exemplo. Lembre-se: "uma condição ou risco de corrida é uma falha em um sistema ou processo eletrônico pelo qual a saída ou resultado do processo é inesperada e criticamente dependente da sequência ou do tempo de outros eventos ". ( fonte )
Nick Chammas

Respostas:

11

Eu faço isso o tempo todo com meus módulos T-SQL.

Basicamente, tudo o que você precisa fazer é executar seus módulos a partir de duas ou mais conexões em loop por alguns minutos . Normalmente, todos os problemas em potencial são expostos em alguns minutos, supondo que você tenha uma caixa do SQL Server com CPUs decentes.

Eu escrevi alguns exemplos aqui e aqui .

AK
fonte
4

Normalmente, eu trabalho com a ferramenta de linha de comando do RDBMS, apenas com 2 (ou mais) instâncias da CLI iniciadas. Você pode reproduzir um por um e, como uma corrida (que pareceria um RPG de ação), as instruções SQL que sua camada de aplicativo está enviando. Você deve experimentar / sentir os sistemas de bloqueio em ação, pois sua CLI "travará" um pouco, aguardando a liberação dos bloqueios da outra CLI.

Se isso parecer claro como lama, não hesite em dizer isso ;-)

Julien
fonte
você poderia dar um exemplo passo a passo? e os testes programáticos podem ser escritos para fazer a mesma coisa?
Xenoterracide
1

As condições de corrida exigem vários encadeamentos de execução; portanto, para testar a unidade, você precisará iniciar um ou mais encadeamentos. No Oracle, eu usaria o DBMS_Scheduler para executar um processo para simular um segundo usuário. Se o PostgreSQL / Perl tiver uma maneira de iniciar um segundo processo programaticamente, você poderá fazer algo assim:

Processo 1 Processo 2

Iniciar processo 2. >>                            
Atraso para permitir que 2 façam seu trabalho. 
. Bloquear linhas ou alterar dados.
. Atraso para permitir que 1 faça seu trabalho.
Tente bloquear linhas ou alterar dados. .
Verifique para garantir o manuseio adequado. .
Termina. .
                                                Termina.

É bom ver pensando em como lidar com as condições da corrida e, mais importante, como testá-las por unidade.

Leigh Riffel
fonte
Eu não descreveria esses testes como testes de unidade, porque os testes de unidade devem ser executados exatamente da mesma maneira todas as vezes. As condições de corrida falham envolvem processos intermitentemente, não exatamente da mesma maneira todas as vezes.
AK
@AlexKuznetsov Você está certo de que condições inesperadas de corrida podem se mostrar intermitentemente, no entanto, o OP está se referindo às condições esperadas que ele acredita que o código esteja manipulando. Essas condições específicas podem ser reproduzidas com precisão e o manuseio verificado com um teste de unidade.
precisa
-2

Contanto que você bloqueie linhas, não deve entrar em condições de corrida, pois isso geralmente é causado quando não há bloqueio.

Mas você pode ficar em um impasse se uma pergunta a bloquear por muito tempo.

É difícil testar, pois o tempo para consultas pode mudar quando o banco de dados cresce.

As consultas que funcionam bem com 100.000 linhas de dados de teste ficam fora do gráfico com 10.000.000 linhas.

Esse tipo de problema pode ser muito difícil de encontrar com antecedência, mas muitos bancos de dados têm algum método para identificar consultas lentas.

Ao usá-lo regularmente, você poderá interceptar todas as consultas com problemas com amplo aviso.

Se você trancar sozinho, é outra história, mas não posso ajudar.

Nick Chammas
fonte
@darioo lol Eu pensei que talvez wn fosse um acrônimo para alguma coisa ... idk, o que ele quis dizer com "faça o bloqueio por conta própria" Se ele não quer dizer com um ORM, verifiquei o código que meu ORM produz, certamente não faz o travando direito. Qual é um dos motivos pelos quais eu gostaria de poder testar os possíveis cenários de condições de corrida.
Xenoterracide
Sim eu quis dizer própria, e, normalmente, as alças de drivers de banco de dados bloqueio, fileira, mesa ou possivelmente campo, mas estou apenas abrindo a possibilidade de que você use algum DB que não lidar com bloqueio;)
.. Eu tenho certeza que se eu tiver uma transação múltipla afirmação de que o meu DB não vai saber quais linhas para bloquear automagicamente ... coisas como select for updatenão existiria se eles fizeram ...
xenoterracide