Por que gravações simultâneas não são permitidas em um banco de dados SQLite?

79

Estou fazendo programação de banco de dados usando Java com SQLite.

Descobri que apenas uma conexão de cada vez com o banco de dados possui recursos de gravação, enquanto muitas conexões ao mesmo tempo têm capacidade de leitura.

Por que a arquitetura do SQLite foi projetada assim? Contanto que as duas coisas que estão sendo gravadas não sejam gravadas no mesmo local no banco de dados, por que duas gravações não podem ocorrer ao mesmo tempo?

Biqueira de aço
fonte
5
relacionada (possivelmente uma duplicata): SQLite com dois processos python acessá-lo: uma leitura, uma escrita
mosquito
5
Porque o SQLite foi projetado para ser "leve". Pouca memória e baixo processamento com desempenho. Pense em como você faria o SQLite manipular várias gravações no mesmo arquivo. O design atual é fácil de implementar - o arquivo inteiro está bloqueado e outros precisam esperar. Para lidar com a simultaneidade de gravação em um nível mais baixo de granularidade, é necessário o bloqueio de linhas / páginas que você obtém dos RDMSs. Se a exigência exige gravação de concorrência, em seguida, SQLite não é um candidato e em vez disso, você deve olhar para RDBMS leves: en.wikipedia.org/wiki/...
Thomas Carlisle

Respostas:

157

Como "várias gravações simultâneas" é muito, muito mais difícil de realizar no mecanismo de banco de dados principal do que um único gravador e vários leitores. Está além dos parâmetros de design do SQLite, e incluí-lo provavelmente subverteria o tamanho e a simplicidade deliciosamente pequenos do SQLite.

O suporte a altos graus de simultaneidade de gravação é uma marca registrada de grandes mecanismos de banco de dados, como DB2, Oracle, SQL Server, MySQL, PostgreSQL, NonStop SQL e Sybase. Mas é tecnicamente difícil de realizar, exigindo estratégias abrangentes de controle e otimização de simultaneidade, como bloqueio de banco de dados, tabela e linha ou, em implementações mais modernas, controle de simultaneidade com várias versões . A pesquisa sobre esse problema / exigência é volumosa e remonta a décadas .

O SQLite tem uma filosofia de design muito diferente da maioria dos DBMSs centrados no servidor que oferecem suporte a vários gravadores. Ele foi projetado para trazer o poder do SQL e do modelo relacional para aplicativos individuais e, de fato, ser incorporado em cada aplicativo. Esse objetivo requer trocas significativas. Não é necessário adicionar a infraestrutura significativa e a sobrecarga necessárias para lidar com vários gravadores simultâneos.

A filosofia pode ser resumida por uma declaração na página de usos apropriados do SQLite :

O SQLite não concorre com os bancos de dados cliente / servidor. SQLite compete com fopen ().

Jonathan Eunice
fonte
41
+1. SQLite é um banco de dados em processo. Não existe um árbitro central como em um banco de dados baseado em servidor. Os escritores teriam que cooperar diretamente e confiar um no outro. Um único escritor malicioso pode causar estragos apenas por não cooperar.
Jörg W Mittag
12
Além disso, alguns dos ambientes em que o SQLite executa podem nem mesmo suportar vários processos.
precisa saber é o seguinte
1
Presumivelmente, uma gravação maliciosa já pode causar estragos ao não cooperar. Eles não podem usar o código SQLite para fazê-lo, mas eles podem ter seu próprio código, que poderia ser apenas uma chamada para desvincular ()
bdsl
12
Em aplicativos simultâneos, não há muito meio termo. Você obtém simultaneidade, consistência e integridade dos dados em praticamente 100% do tempo, inclusive sob condições desafiadoras e casos extremos, ou não. Caso contrário, é frágil, lento e propenso a acidentes, e as pessoas param de confiar muito rapidamente. Mas acertar rotineiramente é diabolicamente difícil. Não há muitas circunstâncias em que os escritores possam, por falta de grande apoio, coordenar gravações intercaladas por conta própria.
Jonathan Eunice
8
@bdsl Bancos de dados de qualquer tipo devem assumir que os escritores não serão bem-comportados para não perder dados. Os autores SQLite o posicionam como um concorrente fopen(), portanto, considere todo o penteado que vem com a gravação simultânea em um arquivo de texto simples.
Blrfl
12

Porque não há servidor que possa dizer se as coisas devem ser gravadas no mesmo local ou não. Existem apenas dois processos tentando gravar em um arquivo.

Conforme apontado em um comentário, gravações simultâneas também podem ser suportadas por um encadeamento interno. Não tenho certeza de como isso funcionaria (também não pensei muito nisso). Enfim, aqui está o porquê do SQLite não usar threads: o Dr. Hipp acha que os threads são ruins.

O fato de o DR Hipp achar que os threads são ruins está documentado nas Perguntas frequentes do SQLite .

Goyo
fonte
2
Isso explica o motivo técnico pelo qual gravações simultâneas não são permitidas, mas não o motivo pelo qual a decisão de design foi tomada.
Robert Harvey
3
A decisão de projetar o SQLite para que ele lide apenas com uma gravação por vez.
Robert Harvey
7
@ Goyo não é necessário um servidor para lidar com gravações simultâneas: da mesma forma que um servidor de banco de dados é um processo separado, pode haver um thread separado interno ao SQLite que atenda ao mesmo objetivo. Robert Harvey está correto: uma decisão de design foi tomada pela equipe do SQLite e não tem nada a ver com a capacidade de uma única biblioteca lidar com gravações simultâneas (porque, em teoria).
1
Essa resposta me parece boa. Para lidar com gravações simultâneas, parece que seria necessário ter um servidor ou uma implementação sqlite com vários threads. Como os dois foram descartados por outras decisões de design, a implementação de gravações simultâneas seria extremamente difícil.
jpa
5
@jpa: SQLite consegue sincronizar o bloqueio entre vários processos / threads sem um "servidor". Um "servidor" não é necessário - usando bloqueio / sincronização / IPC / SO fornecido pelo sistema operacional, o que for suficiente, mas torna-se complexo rapidamente. O "encadeamento interno" mencionado na postagem não faz sentido.
Mat