Borland InterBase 7.1 x Microsoft SQL Server 2000 - Parte 1

O Borland InterBase 7.1 é um banco de dados poderoso e atende os padrões SQL, podendo ser embutido em aplicações e utilizado em aplicações específicas. Os desenvolvedores e arquitetos de aplicações ao avaliar o InterBase descobrem significativas vantagens frente ao Microsoft SQL Server, as quais podemos destacar:

• Maior concorrência em ambientes de leitura e gravação;
• Maior flexibilidade no suporte a trigger;
• Recuperação mais rápida em queda de servidores;
• Gerenciamento de eventos mais fácil;
• Mais opções de distribuição;
• Suporte há várias plataformas;
• Requisitos de servidores menores;
• Baixa exigência de hardware;
• Tempo de treinamento menor;
• Baixo custo de treinamento;
• Baixo custo de licenciamento.

Nesse artigo iremos detalhar algumas destas vantagens.

As aplicações de hoje que embutem o banco de dados criam um ambiente que consiste na leitura e gravação de dados, no caso de relatórios criam transações que requerem uma maior leitura do banco. Quando selecionamos dados precisamos de uma visão dos dados consistente, os locks requisitados pelo usuário do SQL Server impedem que outros usuários acessem os dados que estão sendo analisados.

O engine do InterBase é projetado para fornecer dados consistentes sem obstruir as alterações de outros usuários. Com InterBase a leitura nunca bloqueia a gravação, somente as gravações bloqueiam as gravações.

O modelo de concorrência do InterBase é completamente diferente. Com InterBase você não tem que se preocupar como fazer, com SQL Server os locks sempre são requisitados e negam o acesso às tabelas.

O InterBase tem todos os atributos chaves que são críticos para aplicações embutidas e aplicações remotas. É mais fácil para uma equipe de desenvolvimento aprender a usar, distribuir e não requisitar nenhuma manutenção em ambiente de produção. InterBase é um sexto da instalação mínima do SQL Server, o InterBase ainda fornece suporte SMP, suporte a plataformas Windows, sofisticado otimizador de query, lock em nível de linha, recuperação imediata de servidores em caso de queda, diversos níveis de isolamento transacional que garantem dados consistentes a qualquer hora, rico dialeto de SQL, triggers a níveis de antes (Before) e depois (After) de serem disparadas, controle total da ordem de execução das triggers, stored procedures, backup on-line, alterações on-line da estrutura do banco de dados, replicação e habilidade de disparar eventos no banco de dados que sejam capturados pela aplicação cliente.

O InterBase diminui o custo do seu projeto de 3 maneiras:

  1. Os custos de licença do InterBase são menores que o do SQL Server;
  2. O tempo de treinamento de sua equipe é menor. São necessários 22 dias de treinamento em sala de aula para preparar um profissional para ser um administrador de banco de dados (DBA) SQL Server e tentar a certificação - www.microsoft.com/traincert/mcp/mcdba/mcdba.asp. Essa informação é baseada nos cursos oficiais microsoft, mais precisamente na certificação MCDBA. InterBase é fácil de aprender e seu treinamento é projetado para 5 dias, capacitando o profissional a administrar o banco de dados. Aos profissionais que já estejam acostumados a técnicas de banco de dados podem encontrar todas as referências na documentação do InterBase;
  3. Seus desenvolvedores não precisam perder tempo em buscar soluções criativas para burlar as limitações do banco de dados tais como: conflito de locks, escalonamento de lock, limitação de controle de triggers (After e Before) limitação em determinar a ordem em que as triggers irão ser disparadas e a falta de eventos.

Escolhendo o banco de dados para o seu projeto
Não é difícil criar checklist de atributos necessários ao seu projeto de banco de dados. Entretanto, avaliar uma lista de simples características não é o bastante. A etapa mais crítica para se definir o banco de dados correto para a sua aplicação é o comportamento do banco de dados quando você examinar as situações reais que sua aplicação irá encontrar pela frente. Veremos nesse artigo o comportamento do InterBase e do SQL Server em algumas situações que são comuns de se enfrentar no mundo dos negócios.

Consistência x Concorrência
Vamos dizer que você tem um sistema de gerenciamento de inventário e com muitos itens em vários estoques. O sistema deverá gerar um relatório quando solicitado com a posição exata dos itens. Esta solicitação usará nível de isolação transacional read commited, a seguinte seqüência de eventos pode ocorrer:

  1. Uma transação de leitura que totalize o valor dos artigos agrupados por estoque;
  2. A transação de leitura faz a varredura dos registros para o estoque de São Paulo;
  3. Outro usuário começa uma transação de update que move 1.000 barras de ouro de São Paulo para o Rio de Janeiro;
  4. A transação que executou o update efetua o commit;
  5. A transação de leitura lê (seleciona) os registros do Rio de Janeiro.

A transação de leitura agora conta 1.000 barras de ouro em São Paulo e no Rio de Janeiro.

Você pode facilmente evitar este problema no SQL Server usando o nível de isolamento transacional Serializable para a transação de leitura. Este nível de isolamento garante que sua transação não verá as mudanças feitas por outros usuários durante a vida da transação.

Entretanto, realizar esta operação no SQL Server travará a tabela inteira ou range selecionado na cláusula WHERE. Quando o intervalo do lock for restrito a um grupo de registros podem impedir inserções de registros quando necessários. Considere o seguinte SELECT:

SELECT * FROM CLIENTES
WHERE CIDADE >= 'Campinas' And <= 'Rio de Janeiro'

Suponha que existam registros na tabela onde as cidades Barretos, Lins e São Paulo serão percorridos pelo SELECT para efetuar a pesquisa, assim sendo estes registros estão travados (locked). Infelizmente, isto significa que você não pode inserir registros cujo valor seja maior do que Barretos e menor que Campinas, mesmo que estes registros não estejam incluídos na cláusula WHERE, porque este range está coberto pelo range do lock. Você não poderia inserir registros cujo valor fosse maior do Rio de Janeiro e menor que São Paulo pela mesma razão.

Enquanto a transação estiver selecionando os dados, para retornar ao cliente, não será possível inserir/alterar registros na tabela. Neste exemplo, enquanto os dados são totalizados, qualquer inserção ou alteração não poderá ser efetuada por outros usuários até que esta transação finalize. Com o InterBase isso não acontece graças ao engine de versionamento. Ao retornar o inventário, por exemplo, o que irá acontecer com o InterBase será o seguinte:

  1. A transação de leitura com nível de isolamento snapshot será iniciada. Snapshot é o padrão, se alterar a transação vai funcionar do mesmo jeito e não ocorrerá o lock, pois o foco deste exemplo é mostrar o lock;
  2. A transação seleciona os registros do estoque de Barretos. Claro que é a mesma situação;
  3. Outro usuário inicia uma transação que executa um update para mover 1.000 barras de ouro do estoque de Barretos para o Rio de Janeiro;
  4. O update quando executado vê a última versão do registro e cria uma nova com os novos valores;
  5. A transação que executou o update executa o commit;
  6. A transação de leitura seleciona o registro alterado no Rio de Janeiro, esta transação detecta que a versão corrente do registro foi criada por uma transação que iniciou após a primeira transação. Assim sendo, a transação irá procurar na lista de versões daquele registro, pela última versão do mesmo que tenha sido comitada.

Com isso o InterBase fornece uma visão consistente dos registros no banco de dados sem bloquear os registros para alteração.

Deadlocks
Suponha que o usuário A executa um SELECT que retorna todos os registros da tabela de peças. O usuário B também seleciona todos os registros da tabela de peças. Ambos os usuários devem ter uma visão consistente dos dados selecionados. O usuário A tenta atualizar até o 100º registro e o usuário B tenta atualizar a partir do 101º.

Com o SQL Server usando transações com nível de isolamento repeatable read ou Serializable, neste cenário ocorre deadlock mesmo que os dois usuários estejam atualizando ranges de registros diferentes.

Como isso pode acontecer?
O usuário A obtém um lock compartilhado na tabela quando os registros são lidos. O usuário B obtém também um lock compartilhado na tabela quando lê os registros. Quando o usuário A tenta atualizar os 100 registros, ele precisa de lock exclusivo no registro e converte este lock compartilhado na tabela em lock exclusivo para evitar outros locks.

Entretanto a intenção de efetuar o lock exclusivo é incompatível com o usuário B que está com o lock compartilhado e não pode conceder o acesso. Quando o usuário B tentar atualizar partir do 101º registro ele não pode converter seu lock compartilhado na tabela em lock exclusivo devido ao outro usuário estar com lock compartilhado.

Isto é chamado de conversão de deadlock.

Conversão de lock não ocorre no InterBase. No InterBase o lock é efetuado individualmente por linha, para cada linha que for atualizada e no momento da atualização. O único tipo de deadlock que pode ocorrer no InterBase é o deadlock cíclico, que é o aviso do banco de dados para um usuário que está tentando atualizar um registro que está sendo alterado por outro, comum a todos os bancos de dados.

Imagine que o usuário A atualiza e trava o registro 100 e tenta atualizar o registro 200 que está travado pelo usuário B, depois o usuário B tenta atualizar o registro 100, este foi travado pelo usuário A quando o mesmo o atualizou. Neste caso, de duas opções irá ocorrer uma: se o usuário especificar na transação NOWAIT, o usuário A irá receber imediatamente um erro quando tentar travar o registro, pois este registro está travado pelo usuário B e vice-versa.

Se os dois usuários usarem em suas transações o parâmetro WAIT para efetuar o lock nos registros, então o gerenciador de locks irá detectar deadlock e selecionar uma transação para efetuar o roolback.

Conflitos de Locks
Considere o caso quando o usuário A altera o registro e sai sem efetuar o commit em sua transação e o usuário B executa um SELECT que inclua este registro.

Usando o SQL Server, a transação do usuário B irá esperar até que o usuário A libere o registro, ou seja, quando o commit for efetuado.

Por padrão, não há nenhum período mandatário de time-out e nenhum método para saber se o registro está travado ou não antes de efetuar o lock, exceto tentando acessar os dados e efetuando tratamento de erro. Para se prevenir de uma espera indefinida pela liberação do registro, você pode definir tempo de time-out para o lock de registro, usando o comando SET LOCK_TIMEOUT, entretanto isso irá afetar todas as transações para aquela conexão.

InterBase é menos restritivo e mais flexível. Usando transações com nível de isolamento snapshot você irá selecionar sempre a última versão do registro comitada a partir do momento em que sua transação foi iniciada. Usando nível de isolamento read commited o InterBase lhe dá 3 opções:

  1. Você pode ler a última versão do registro comitada mesmo que uma versão do registro ainda não tenha sido comitada;
  2. Você pode esperar até que uma versão de registro não comitada seja efetuado o commit ou roolback;
  3. Você pode receber um aviso imediato de uma exceção que uma versão do registro não comitada existe.

Estes ajustes estão disponíveis no nível da transação, ou seja, a configuração que você faz para uma transação não limita suas configurações para outras conexões na mesma conexão.

Um grande abraço e até a 2ª Parte desse artigo.