Eu sou novo na transação. Quando li o livro "Transactional Information Systems", é mencionado que o B-tree usa o bloqueio de intervalo de chaves para garantir a serialização. É verdade que todos os acessos à relação devem ser realizados através da mesma árvore B para garantir a serialização?
Se bem entendi, não há como garantir a serialização se os acessos forem por diferentes índices . Veja o exemplo a seguir.
Suponha que existam dois índices na mesma relação, ou seja, uma árvore B e um índice de hash, e existam duas transações.
Primeiro, uma transação lê a relação usando o índice de hash, por exemplo, fetchkey(16)
para buscar o registro (atualmente ausente) com a chave 16
e não encontra correspondência. Como o hash não possui bloqueio de intervalo de chaves, ele não pode bloquear a próxima chave. Em seguida, a outra transação insere um registro com a chave '16' por meio da árvore B. A inserção será bem sucedida, levando a um fantasma.
Os mecanismos de travamento e armazenamento são independentes.
Como os bloqueios são independentes do armazenamento, não importa como o armazenamento é acessado. Uma consulta pode acessar dados por meio de uma B-Tree. Um segundo pode usar uma árvore B separada, um índice de hash, a tabela base ou qualquer outra estrutura. As páginas de dados podem ser trocadas para o disco. Não importa, os bloqueios ainda serão respeitados.
Se o seu DBMS já tiver BTrees, o bloqueio de intervalo de chaves é um detalhe de implementação conveniente.
Na ausência de BTrees, uma implementação diferente poderia ser o bloqueio de predicado. Neste, as cláusulas WHERE de consultas em execução são comparadas. Se a cláusula where de uma nova consulta entrar em conflito com a de uma consulta existente, as novas filas de consulta.
Como exemplo, digamos que temos linhas com IDs 10, 20, 50, 100. O predicado da consulta 1 é
..WHERE ID between 15 and 75
. O bloqueio de intervalo deve cobrir as teclas existentes mais baixas e mais altas. Então o bloqueio é feito em 10..100. Agora, se a consulta 2 tentar escrever..WHERE ID = 88
, ela será bloqueada porque 88 está dentro do intervalo bloqueado de 10..100.Com o bloqueio de predicado, no entanto, o sistema reconheceria que o predicado da consulta 2 (88) está fora do intervalo da consulta 1 (15..75) para que a consulta 2 possa prosseguir. Não há risco de fantasmas, portanto, o resultado é serializável.
Os predicados podem ser arbitrariamente complexos, portanto, corresponder cada nova consulta a cada consulta já em execução não é trivial. Provavelmente a taxa de transferência adicional não pagaria o custo em um sistema ocupado.
Para índices de hash, existem coisas como hashes que preservam a ordem. Para nosso exemplo, isso significaria que hash(100) é maior que hash(75) e o bloqueio de intervalo ainda pode ser aplicado.
Existem vários tipos e níveis de bloqueio. Um nível mais alto de bloqueio é um bloqueio no próprio objeto de tabela inteiro. Isso incluiria todos os índices dessa tabela. Geralmente isso acontece quando um determinado limite de linhas está sendo modificado em relação ao número total na tabela e é conhecido como escalonamento de bloqueio.
Consulte a pergunta do DBA.StackExchange intitulada O que é escalonamento de bloqueio? para mais informações.