SQLite com dois processos python acessando: uma leitura, uma escrita


22

Estou desenvolvendo um pequeno sistema com dois componentes: um pesquisa dados de um recurso da Internet e os converte em dados sql para persistir localmente; o segundo lê esses dados sql da instância local e os serve via json e uma API repousante.

Originalmente, eu estava planejando manter os dados com o postgresql, mas como o aplicativo terá um volume muito baixo de dados para armazenar e tráfego para servir, pensei que isso fosse um exagero. O SQLite está pronto para o trabalho? Adoro a idéia do tamanho reduzido e não há necessidade de manter outro servidor sql para essa tarefa, mas estou preocupado com a simultaneidade.

Parece que, com o log de gravação antecipada ativado, a leitura e gravação simultânea de um banco de dados SQLite podem ocorrer sem bloquear nenhum processo do banco de dados.

Uma única instância SQLite pode sustentar dois processos simultâneos acessando-a, se apenas uma lê e a outra grava? Comecei a escrever o código, mas queria saber se isso é uma aplicação incorreta do SQLite.


3
@gnat Cool. Uma única instância SQLite pode sustentar dois processos simultâneos acessando-a, se apenas uma lê e a outra grava? Comecei a escrever o código, mas queria saber se isso é uma aplicação incorreta do SQLite.
bb

Apenas um aviso. Na minha empresa anterior, estávamos usando SQL (MS e Oracle Express) para algum armazenamento e sempre sentimos que, com o pouco que armazenávamos, não precisávamos de um banco de dados completo. Então, em um dos lançamentos, decidimos fazer exatamente o que você está fazendo. Substitua esses produtos pelo SQLite. Tínhamos exatamente a mesma coisa, um gravador que colocaria os dados no disco e atualizaria o TOC baseado em SQL e o processo de leitura (vários threads) que leria o TOC para determinar quais dados recuperar. Não sei sobre SQLite estes dias, mas a pouca concorrência que funcionou em acabou por ser uma grande dor no ...
DXM

... o traseiro. Não me lembro de todos os detalhes, mas acho que quando um processo tentava trancar e não conseguia porque outro estava lendo, ele dormia por algo louco como 20 a 30 segundos. Acabamos criando um encadeamento dedicado que era responsável pelo acesso ao SQLite e, em seguida, tivemos nossos processos e todos os encadeamentos em série, serializando suas solicitações de banco de dados para esse encadeamento. Em retrospectiva, eu provavelmente não teria ido com o SQLite novamente.
DXM 9/10

1
@ DXM obrigado pelo aviso, mas depois de executar alguns testes, não encontrei nada parecido. Eu sei que o sqlite sofreu uma grande reforma com a versão 3, que foi por volta de 2004, então me pergunto se sua experiência negativa remonta antes desse período.
bb

1
... você mesmo, em vez de confiar nos esquemas de bloqueio do SQLite. Eu não fiz o trabalho sozinho, era outra equipe, mas mantive o controle principalmente para fornecer feedback e por curiosidade. Também estive on-line, fiz algumas leituras independentes e encontrei a página do autor original. Ao ler isso, tive a impressão de que o inventor do SQLite simplesmente odiava threads e não via por que alguém os usaria, então a) o banco de dados não foi projetado com eles em mente eb) bloqueios / proteção foi meio que adicionado / invadido como uma reflexão tardia, porque muitas pessoas pediram.
DXM

Respostas:


25

Você está procurando a documentação Bloqueio de arquivos e simultaneidade .

Os processos SQLite usam uma série de bloqueios para lidar com simultaneidade; para ler, vários processos podem obter um SHAREDbloqueio.

Um processo que grava precisará obter um RESERVEDbloqueio e somente quando realmente for necessário liberar as alterações no disco, ele será movido para o PENDINGestado. Qualquer processo de leitura precisará desbloquear o arquivo, após o qual o processo de gravação poderá ser movido EXCLUSIVEpara gravação no arquivo de banco de dados real.

Como o processo do gravador só precisa bloquear o arquivo do banco de dados para gravações reais (liberações de memória, confirmações), uma configuração com apenas um leitor e apenas um gravador funcionará muito bem. Eu esperaria que ele funcionasse tão bem, se não melhor, como uma configuração com apenas um processo fazendo toda a leitura e escrita.

O SQLite é menos adequado quando você tem vários processos gravando frequentemente no mesmo banco de dados, pois a gravação exige a obtenção do PENDINGbloqueio exclusivo para serializar as alterações.


Obrigado pela resposta completa Martijn! Eu alguns scripts para fazer alguns testes e parece que dois processos terão prazer em ler e gravar uma única instância sqlite simultaneamente. Eu estava fazendo solicitações simultâneas de leitura e gravação disparando a cada 1/100 de segundo e ainda não recebia uma exceção de banco de dados bloqueada. Estranhamente, a única vez que recebi uma mensagem de erro "banco de dados bloqueado" foi quando tentei manualmente (com o cliente de linha de comando sqlite3) excluir algumas linhas enquanto as solicitações de leitura eram disparadas do meu script em 1/100 de segundo. Gostaria de saber se o pysql tenta novamente uma gravação automaticamente após esse erro.
bb

10

Só queria acompanhar e informar a todos que a implementação foi bem-sucedida. Trabalhar com SQLite foi um verdadeiro prazer e, com apenas um processo gravando por vez, nunca tivemos problemas com travamentos ... mesmo com leituras simultâneas muito rápidas de um processo secundário.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.