Pergunta

Há um sistema pequeno, onde uma tabela de banco de dados como fila no MSSQL 2005. Vários aplicativos estão escrevendo para esta tabela, e um aplicativo está lendo e processando de maneira FIFO.

Eu tenho que torná -lo um pouco mais avançado para poder criar um sistema distribuído, onde vários aplicativos de processamento podem ser executados. O resultado deve ser que o aplicativo de processamento 2-10 deve ser capaz de ser executado e eles não devem interferir um ao outro durante o trabalho.

Minha idéia é estender a tabela de filas com uma linha mostrando que um processo já está funcionando nela. O aplicativo de processamento atualizará primeiro a tabela com o IDETifyer e, em seguida, solicita os registros atualizados.

Então, algo assim:

start transaction
update top(10) queue set processing = 'myid' where processing is null
select * from processing where processing = 'myid'
end transaction

Após o processamento, ele define a coluna de processamento da tabela para outra coisa, como 'feito' ou qualquer outra coisa.

Eu tenho três perguntas sobre essa abordagem.

Primeiro: isso pode funcionar nesse formulário?

Segundo: se estiver funcionando, é eficaz? Você tem outras idéias para criar essa distribuição?

Terceiro: no MSSQL, o bloqueio é baseado em linha, mas depois que uma quantidade de linhas é bloqueada, a trava é estendida para toda a tabela. Portanto, o segundo aplicativo não pode acessá -lo, até que o primeiro aplicativo não libere a transação. Quão grande pode ser a seleção (superior x) para não travar a tabela inteira, apenas criar travas de linha?

Foi útil?

Solução

Isso funcionará, mas você provavelmente descobrirá que encontrará bloqueio ou deadlocks, onde vários processos tentam ler/atualizar os mesmos dados. Eu escrevi um procedimento para fazer exatamente isso para um de nossos sistemas que usa alguma semântica de travamento interessante para garantir que esse tipo de coisa funcione sem bloqueio ou deadlocks, descrito aqui.

Outras dicas

Essa abordagem parece razoável para mim e é semelhante à que eu usei no passado - com sucesso.

Além disso, a linha/ tabela será bloqueada apenas enquanto as operações de atualização e selecionamento ocorrerem, por isso duvido que a pergunta da linha vs tabela seja realmente uma consideração importante.

A menos que a sobrecarga de processamento do seu aplicativo seja tão baixa que seja insignificante, eu manteria o valor "superior" baixo - talvez apenas 1. É claro que isso depende inteiramente dos detalhes do seu aplicativo.

Dito tudo isso, eu não sou um DBA e, portanto, também estará interessado em mais respostas especializadas

Em relação à sua pergunta sobre bloqueio. Você pode usar uma dica de travamento para forçá -la a travar apenas linhas

update mytable with (rowlock) set x=y where a=b

O maior problema dessa abordagem é que você aumenta o número de 'atualizações' na tabela. Tente isso com apenas um processo consumindo (atualização + excluir) e outros inserindo dados na tabela e você descobrirá que, em cerca de um milhão de registros, ele começa a desmoronar.

Prefiro ter um consumidor para o banco de dados e usar filas de mensagens para fornecer dados de processamento a outros consumidores.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top