Redes - Programas Multiusuários
|
Conteúdo
Introdução.
Mesmo que você não desenvolva sistemas para um ambiente de rede, precisa saber
alguns conceitos relativos ao assunto.
Naturalmente o Visual Basic fornece acesso compartilhado ao banco de dados do
sistema e vários usuários poderão acessar os dados ao mesmo tempo; o VB faz o
bloqueio e o desbloqueio das páginas dos dados quando necessário, automaticamente.
Se você quiser que os dados de sua aplicação sejam acessados por um único usuário,
este é o modo exclusivo , terá que informar isto ao VB.
Para abrir um arquivo de dados no VB usamos o método OpenDatabase, vejamos então
sua sintaxe:
Set database = workspace.OpenDatabase(dbname[, exclusive[, read-only[, source]]]
Observe o argumento opcional exclusive , ele pode assumir dois valores:
-True - Abre o arquivo no modo exclusivo , ou seja , não compartilhado.
-False - Abre o arquivo no modo compartilhado.
Se você omitir este argumento o arquivo é aberto no modo compartilhado.
O argumento read-only também pode assumer dois valores:
-True - Abre o arquivo no modo read-only , isto é, somente leitura.
-False - Abre o arquivo no modo read/write , isto é , leitura e escrita.
Se voce omitir este argumento o arquivo é aberto no modo leitura e escrita.
Portanto se você usa a seguinte sintaxe para abrir um banco de dados do seu
sistema:
dim db as database
set db = dbengine.workspaces(0).OpenDatabase(app.path & "\nome_arquivo")
O seu arquivo estará sendo aberto no modo compartilhado. Até aqui tudo bem !
Conteúdo
O acesso aos Dados.
O limite mais restritivo que podemos impor a um banco de dados é sua abertura
em modo exclusivo.
Isto impedirá que qualquer usuário tenha acesso ao banco de dados enquanto ele
estiver sendo utilizado.(Isto inclui todas as suas tabelas e consultas.)
Vejamos a sintaxe utilizada para este caso:
dim db as database
set db = dbengine.workspaces(0).OpenDatabase(app.path & "\nome_arquivo",True)
A tentativa de abrir o arquivo em uso irá gerar uma mensagem de erro pelo VB.
Quer algumas boas razões para usar o acesso exclusivo ?
Use-o em operações que afetem todo o banco de dados tais como:
-Compactação do banco de dados
-Atualização de tabelas inteiras
-Alteração da estrutura do banco de dados(inclusão de tabelas, índices, etc...)
Se você não quiser ser tão radical, pode restringir o acesso á tabela em
uso pelo seu sistema.
Para fazer isto utilizamos as opções do método OpenRecordSet para negar
acesso de leitura e/ou gravação ás tabelas , vamos a sua sintaxe:
Set variable = database.OpenRecordset(source[, type[, options]])
Vejamos as opções mais usadas:
-dbDenyRead Impede os usuários de examinar os dados contidos na tabela,até você fechá-la.
(Disponível para recordsets do tipo tabela)
Você usuará esta opção quando for necessário atualizar informações na tabela inteira.
Ex: Dim db as database,rs as recordset
set rs=db.openrecordset("nome_tabela",DbOpenTable,dbDenyRead)
-dbDenyWrite Os usuários podem visualizar os dados mas não podem atualizar as informações da tabela,
nem incluir novos registros ,até você fechá-la.(Válido para Tabelas,Dynasets e Snapshot)
Você pode usar esta opção quando estiver incluindo novos registros na tabela e não
houvesse modificações nos registros existentes.
Ex: Dim db as database,rs as recordset
set rs=db.openrecordset("nome_tabela",DbOpenTable,dbDenyWrite)
-dbReadOnly Permite somente visualizar os dados da tabela.
Ex: Dim db as database,rs as recordset
set rs=db.openrecordset("nome_tabela",DbOpenTable,dbReadOnly)
Você pode usar esta opção em tabelas de pesquisa.
Uma outra maneira de restringir o acesso a apenas leitura , é utilizar
Snapshots.Eles sempre são de somente leitura.
A vantagem dos Snapshots é que eles ficam armazenados na memória.
Ex: Dim db as database,rs as recordset
set rs=db.openrecordset("nome_tabela",DbOpenSnapshot)
-dbAppendOnly Permite somente a inclusão de novos registros(Válido somente para dynaset)
Ex: Dim db as database,rs as recordset
set rs=db.openrecordset("nome_tabela",DbOpenDynaset,dbAppendOnly)
Se você tentar abrir qualquer tabela com as restricões acima mencionadas e um outro
usuário já estiver com ela aberta ocorrerá uma mensagem de erro.
Dai conclui-se que o código de tratamento de erros deverá ser utilizado em todos
os lugares onde o método OpenRecordset for utilizado, pois neste caso o método
falhará e você tem que estar preparado para interceptar o erro gerado.
Que tal provarmos tudo isso ? Então vamos lá...
-Primeiro vejamos um exemplo para o caso da abertura do banco de dados nos modos
exclusivo e compartilhado :
- Acesso Exclusivo/Compartilhado.
-A seguir um exemplo que analisa o comportamento do Jet na abertura das tabelas
nas opções dbDenyRead , dbDenyWrite e dbReadOnly :
- Acesso as tabelas - dbDenyRead , dbDenyWrite e dbReadOnly
Nota :Da mesma forma você pode usar as opções descritas acima para criar um dynaset.
Ex: Para criar um dynaset com a opção dbDenyWrite
Set rs = db. OpenRecordset("SELECT * FROM Tabela", DbOpenDynaset, dbDenyWrite)
Conteúdo
Bloqueio de Registros
Se sua aplicação for rodar em um ambiente multiusuário mais cedo ou mais tarde
alguém tentará atualizar um registro que está bloqueado por outro usuário ou
outro usuário tentará modificar um registro que você esta atualizando. E ai...?
Antes de fazer um pedido para editar um registro já existente ou incluir um novo
registro, o Jet irá verificar se nenhum outro usuário esta tentando modificar o
registro ou acrescentando um registro novo , para isso o Jet utiliza a técnica de
bloqueio de registros.
Mas atenção , o jet na não aceita o bloqueio de registros , na verdade o que
ocorre é o bloqueio da página ou páginas contendo o registro. Como uma
página contém 2K (2048 bytes), o bloqueio será efetuado não somente no registro
desejado mas também nos adjacentes , a não ser que o registro tenha exatamente o
tamanho de 2048 bytes.
O jet trabalha então com dois métodos de bloqueios : o pessimista e o otimista.
Vejamos cada um deles:
1-Bloqueio pessimista(O padrão usado pelo VB)
Executa o bloqueio da página que contém o registro no momento que sua aplicação
executar o método Edit
O registro permanecerá bloqueado até ser executado o método Update e os dados
forem gravados no arquivo.
Perceba que enquanto você estiver editando o registro outros usuários não poderão
alterá-lo. Se alguém tentar bloquear a página que contém o registro o Jet retornára
um erro.
A desvantagem do bloqueio pessimista é que se você bloquear o registro para edição
por um período longo , ninguém mais conseguiria editar o mesmo registro e os outros
registros da mesma página além de afetar o desempenho do sistema.
2-Bloqueio otimista
Executa o bloqueio da página contendo um determinado registro somente quando for
invocado o método Update.
O bloqueio é imediatamente liberado quando se completa a operação de atualização.
A vantagem é que a página é bloqueada por um curto período de tempo.
A desvantagem é a possibilidade de outro usuário alterar os dados contidos no
registro entre os instantes em que são empregados os métodos Edit e Update,
se isto ocorrer o Jet retorna um erro.
Com isto em mente você deve levar em conta algumas considerações ao utilizar o bloqueio
de registros. Vejamos :
1-O que fazer caso não seja possível bloquear um registro.
2-Como evitar que o usuário mantenha um registro bloqueado por muito tempo.
3-Determinar qual tipo de bloqueio usar: pessimista ou otimista
No primeiro caso temos os conflitos de bloqueio, ou seja, se um usuário
bloqueou um registro e outro usuário requisitou um bloqueio no mesmo registro
ocorrá um erro.
Como o VB não fornece uma maneira de verificar se um registro está bloqueado,
você tem que estar preparado para os erros de bloqueio implementando um código
de tratamento de erros em todos os lugares onde irá acrescentar ou atualizar os
registros.
Dentre os inúmeros erros que o Jet retorna em ambiente multiusuário existem 3 que
são muito importantes e deles você deve se proteger, vejamos :
-Erro 3167 - O registro foi deletado
Lembre-se que as modificações(alterações,exclusões,etc..) feitas
em um registro somente serão refetidas em um dynaset quando
o VB reler a página que contém o registro.
Neste caso o erro ocorre quando você tentar executar o método
Edit em um registro que já foi deletado por outro usuário
desde a última vez que você leu a página.
-Erro 3197 - Os dados foram modificados; a operação foi interrompida.
Ocorre quando você tenta editar um registro que sofreu modificações
por outro usuário desde a ultima vez que você leu a página.
-Erro 3260 - Impossível atualizar; atualmente bloqueado pelo usuário x
na máquina y.
Ocorre quando você tenta bloquear uma página que já está bloqueada
por outro usuário.
Quanto ao método de bloqueio a utilizar , na maior parte dos aplicativos de banco
de dados, o bloqueio otimista é a melhor opção , mas existirão situações em que
você deverá usar o bloqueio pessimista.
Para estabelecer o método de bloqueio de registro, defina a propriedade LockEdits
da tabela ou do dynaset com que está trabalhando. Assim :
1-Produzir bloqueio Pessimista - LockEdits = True
Dim rs as Recordset
rs.LockEdits = True
1-Produzir bloqueio Otimista - LockEdits = False
Dim rs as Recordset
rs.LockEdits = False
Como dissemos a liberação do bloqueio é automática, mas em aplicativos com intensa
entrada de dados você pode precisar fazer pausas momentâneas no processamento do
aplicativo para permitir ao Jet realizar o seu trabalho de manutenção; para isto
utilizar o método Idle, da seguinte forma:
DbEngine.Idle dbFreeLocks
Bem falar é fácil, vamos tentar provar tudo o que foi dito nesta seção. Vejamos um
exemplo que utiliza os métodos aqui expostos e como o jet se comporta :
-Aguardem exemplo... - Bloqueio de registros.
Conteúdo
AGUARDEM CONTINUAÇÃO...
Retorna