concurrency do MS Access (MDB)

Para um projeto pequeno eu preciso utilizar um database simples com requisitos muito leves: poucas tabelas, não mais do que alguns milhares de registros no total, 2 ou 3 usuários. Eu estou trabalhando no ambiente .NET.

Como um servidor de database (mesmo as edições Express) parece ser um grande exagero neste caso, um database MDB muito simples poderia fazer para a maioria dos requisitos. Estou, no entanto, preocupado com a concorrência. Minha idéia é colocar o arquivo .mdb em um compartilhamento de rede e permitir que os usuários acessem esse arquivo de seus clientes baseados em .NET. O database é principalmente destinado a operações somente leitura, mas os usuários ocasionalmente precisam atualizar / excluir registros também. Se isso não for possível no momento (devido ao bloqueio do database ou qualquer outro), posso manter as atualizações no cliente e processá-las posteriormente.

A questão em si segue esses pontos:

  • Como as leituras simultâneas são tratadas no MDB?
  • Como as atualizações / exclusões concorrentes são tratadas no MDB?
  • Existe um conceito de bloqueios e como posso utilizá-lo em um aplicativo .NET?
  • Colocar o arquivo MDB em uma rede é bom ou horrível?

Como estou trabalhando no .NET, também gostaria de saber como posso detectar problemas de simultaneidade e tomar as medidas adequadas. Ou seja, qual exceção devo pegar e qual ação você recomendaria tomar?

EDIT : Pode ser minha descrição ruim do problema, mas a maioria das respostas parece aconselhar indo para um servidor DB completo. Eu entendo as diferenças e os benefícios de ter uma instalação de servidor e, de fato, implementei um número razoável de projetos no MSSQL e no Oracle. Nesta questão, no entanto, estou preocupado apenas com o Access e seus problemas de simultaneidade, portanto, não sugira um servidor db.

Obrigado pela ajuda.

Essa é uma pergunta antiga, mas ninguém nunca realmente respondeu. Aqui estão as perguntas:

  1. Como as leituras simultâneas são tratadas no MDB?
  2. Como as atualizações / exclusões concorrentes são tratadas no MDB?
  3. Existe um conceito de bloqueios e como posso utilizá-lo em um aplicativo .NET?
  4. Colocar o arquivo MDB em uma rede é bom ou horrível?

As duas primeiras perguntas podem ser respondidas basicamente com uma explicação. Uma ressalva chave aqui: as respostas que estou dando aqui são específicas para Jet MDBs (e suas variantes) e não se aplicam completamente ao novo formato de arquivo introduzido a partir de A2007, ou seja, formato ACCDB. Eu não explorei completamente as implicações da remoção do Jet ULS do ACE e alguns dos comentários abaixo podem assumir o Jet ULS abaixo do capô. Para muitas coisas, você pode replace “arquivo LACCDB” por “arquivo LDB” e os resultados serão os mesmos.

1-2) Leituras / atualizações / exclusões simultâneas

O mecanismo de database Jet é geralmente chamado de database de “servidor de arquivos”, pois não há nenhum demônio do lado do servidor gerenciando E / S com os arquivos de dados no servidor. O que isto significa é que todos os clientes usando um Jet MDB estão lendo o arquivo diretamente.

Isto é, obviamente, uma receita para o desastre, se não houver algum mecanismo embutido para lidar com o access simultâneo ao arquivo.

Jet usa um arquivo de bloqueio de registro, onde se o seu MDB é “MyFile.MDB” o arquivo de bloqueio de registro será na mesma pasta e chamado “MyFile.LDB”. O arquivo LDB registra quais usuários do ULS do Jet têm o arquivo MDB aberto, a estação de trabalho com a qual o usuário está conectado e todas as informações necessárias para negociar problemas de simultaneidade.

Agora, para aqueles que desbravam os mecanismos de database cliente / servidor, isso pode parecer primitivo e perigoso, mas no momento em que o mecanismo de database Jet foi desenvolvido, seu objective era ser usado como um mecanismo de database para pequenos grupos de trabalho. estava concorrendo com outros mecanismos de database, como xBase e Paradox, que usavam arquivos de bloqueio análogos para gerenciar o uso simultâneo de arquivos de dados de vários clientes.

Dentro de um arquivo de database Jet, os bloqueios são aplicados em páginas de dados (que no Jet 4 foram aumentadas para 4K, enquanto no Jet 3.xe antes, eram 2K) ou no nível de registro se a tabela de dados foi originalmente criada para use bloqueio de nível de registro. Nos primeiros dias do Jet 4, o bloqueio em nível de registro era considerado por muitos bastante lento, particularmente quando se usava travamento pessimista, então muitos desenvolvedores do Access nunca usaram nada além de travamento no nível da página (@David Fenton levanta a mão!).

Na verdade, ao usar o bloqueio otimista, você evita a maioria dos problemas de simultaneidade que viriam com o bloqueio pessimista.

Algumas ressalvas:

  1. do DAO, o bloqueio em nível de registro não está disponível e você só obtém bloqueio em nível de página.

  2. do DAO, há várias opções para controlar o bloqueio otimista / pessimista, em particular o argumento LockEdits do método OpenRecordset, mas que também interage com determinada configuração especificada no argumento OpenRecordset Options (por exemplo, a opção dbReadOnly não pode ser usada com LockEdits). Além de bloquear, também há opções para atualizações consistentes / inconsistentes, e tudo isso pode interagir com transactions (por exemplo, alterações em uma transação não-distribuída não serão visíveis para outros usuários e, portanto, não entrarão em conflito com elas, mas pode colocar bloqueios somente leitura nas tabelas envolvidas).

Do ADO / OLEDB, essas estruturas de controle de simultaneidade Jet serão mapeadas para as funções relevantes e argumentos encontrados no ADO / OLEDB. Desde que eu uso Jet somente do Access, eu interajo com ele somente via DAO, então eu não posso aconselhar sobre como você controla estes com ADO / OLEDB, mas o ponto é que o mecanismo de database Jet oferece controle de seu registro de bloqueio ao acessá-lo programaticamente (ao contrário da interface de access) – é apenas mais complicado.

3) bloqueios e .net

Eu não posso oferecer nenhum conselho aqui, além de que você provavelmente usaria o OLEDB como sua interface de dados, mas o ponto é que a funcionalidade / controle de bloqueio está lá no próprio mecanismo de db, então provavelmente há uma maneira de controlá-lo via OLEDB. Pode não ser bonito, no entanto, como me parece que o OLEDB é projetado em torno de arquiteturas cliente / servidor, e o bloqueio baseado em arquivo do Jet pode não ser mapeado para isso de uma maneira elegante.

4) MDB em um compartilhamento de rede

Jet é muito sensível ao menor soluço em qualquer conexão de rede. Por causa disso, as redes de baixa largura de banda podem aumentar a vulnerabilidade dos bancos de dados do Jet abertos através de uma conexão lenta.

Isso ocorre porque grandes partes do arquivo de database precisam ser puxadas pela rede para a RAM do computador local para processamento. Agora, muitas pessoas afirmam erroneamente que todo o arquivo MDB é puxado pelo fio ou que as tabelas inteiras são puxadas pelo fio. Isso não é verdade. Em vez disso, o Jet primeiro solicita os índices (e solicita não mais do que o necessário para atender à consulta) e, a partir desse resultado, determina exatamente quais páginas de dados são necessárias e, em seguida, extrai apenas essas páginas. Isso é surpreendentemente eficiente e rápido.

Além disso, o Jet faz um cache muito inteligente que pode significar que uma primeira solicitação de dados pode demorar um pouco, mas solicitações subseqüentes para os mesmos dados acontecem quase instantaneamente devido ao armazenamento em cache.

Agora, se você não indexou bem suas tabelas, pode acabar puxando a tabela inteira e fazendo uma varredura completa na tabela. Da mesma forma, se você basear critérios em funções do lado do cliente que não fazem parte do dialeto SQL do Jet, você pode acabar puxando uma tabela inteira (ordenar, por exemplo, Replace (MyField, “A”, “Z”) uma varredura completa da tabela). Mas esse tipo de coisa também será ineficiente com uma arquitetura cliente / servidor, portanto, é apenas um design de esquema de senso comum para indexar as coisas corretamente e ter cuidado ao usar UDFs ou funções não compatíveis com Jet. Em geral, as mesmas coisas que são eficientes com cliente / servidor serão eficientes com o Jet (a principal diferença é que com o Jet você está melhor com uma conexão persistente para evitar a sobrecarga de recriar o arquivo LDB, que é significativo).

A outra coisa a evitar é tentar usar os dados do Jet em uma conexão WiFi. Todos sabemos como o Wi-Fi não é confiável e estamos apenas nos perguntando por problemas para tentar trabalhar com dados do Jet em uma conexão WiFi.

A linha inferior:

Se você estiver usando um MDB como um armazenamento de dados para fornecer dados de um servidor da Web, deverá colocar os dados o mais próximo possível da RAM do servidor da Web. Isso significa que, quando possível, em um volume de disco conectado ao servidor da Web físico. Onde isso não for possível, você quer uma conexão LAN rápida e confiável. Atualmente, as LANs de GB em data centers são bastante comuns e ficaria muito à vontade trabalhando com os dados do Jet nesse tipo de conexão.

Para uso compartilhado, por exemplo, várias estações de trabalho cliente executando um aplicativo de desktop VB.NET compartilhando um único Jet MDB como armazenamento de dados, é bastante seguro ter o arquivo de dados em um servidor de arquivos confiável. Sempre que possível, é uma boa ideia colocar seus arquivos do Jet MDB em máquinas que não estão atendendo a vários propósitos (por exemplo, o controlador de domínio que está executando o Exchange, SQL Server e atuando como servidor de arquivos e servidor de impressão pode não ser o melhor local) . Aplicativos como o Exchange podem interferir muito na funcionalidade do servidor de arquivos, e eu geralmente recomendaria nunca colocar arquivos MDB em um servidor que seja multitarefa como um servidor Exchange, a menos que seja um volume extremamente baixo.

Outras considerações:

  1. nunca tente distribuir um MDB em um sistema de arquivos replicado, a menos que todos os usuários estejam usando a mesma réplica. Ou seja, se você tiver dois servidores replicando arquivos entre eles, nem pense em editar o arquivo MDB dos dois servidores. Isso corromperá o arquivo quase imediatamente.

  2. Eu recomendaria contra o armazenamento de qualquer MDB em qualquer coisa diferente de um sistema de arquivos nativos do Windows servido via rede nativa Microsoft SMB. Isso significa que não há Novell, Linux, SAMBA. A principal razão para isso é que aparentemente há ganchos de baixo nível do Jet em alguma funcionalidade de bloqueio de baixo nível no sistema de arquivos do Windows que não são 100% replicados em outro arquivo systsm. Agora, sou muito conservador com relação a isso e muitos desenvolvedores competentes do Access relataram excelentes resultados com servidores de arquivos Novell configurados corretamente (geralmente é necessário que haja alguns ajustes de bloqueio de registros, embora isso possa ser menos relevante nos dias de hoje – não sei nem sei se existe mais o Novell!) e desempenho incrível com servidores de arquivos baseados em Linux executando o SAMBA. Eu sou cauteloso sobre isso e recomendaria qualquer cliente contra ele (isso inclui vários dispositivos SAN, uma vez que não muitos deles são baseados no Windows).

  3. Eu nunca os executaria em qualquer sistema de arquivos virtualizado pelas mesmas razões. No entanto, eu tenho um cliente que tem executado seu aplicativo de access único usuário em Parallels em um Mac Air há vários anos sem um único problema. Mas é um usuário único, então os problemas de bloqueio serão relativamente menores.

Não sei se isso responde às suas perguntas ou não. É tudo baseado em meus 13 anos de uso regular do Jet como desenvolvedor do Access e estudo do único livro publicado no Jet, o Jet Database Engine Programmers Guide (somente para Jet 3.5). Eu não fiz nenhuma citação de verdade, mas se alguém precisar de alguns detalhes sobre qualquer coisa que eu tenha dito, farei a pesquisa se puder.

Eu construí uma dúzia ou mais aplicativos de pequenas empresas no Access ao longo dos anos. A maioria tem um máximo de 10 a 20 usuários ao mesmo tempo. Os bancos de dados são divididos entre um “aplicativo” e um database “de dados”. O desempenho é decente e não há problemas com concurrencia. Também a corrupção tem sido praticamente inexistente desde o Access 2000 SP2.

Há muitas pessoas dizendo: “nunca use o Access” – bem, se for feito corretamente (por um desenvolvedor profissional), o Access é um ótimo pacote de desenvolvimento e eu tenho uma boa vida nisso. Meus clientes estão muito felizes com o que eu construí.

Escrevi dois produtos comerciais que usam um database do Access, executado em um compartilhamento de rede, normalmente para até 10 usuários. Se você não abusar, realmente não há problema; mas como você pode ver, muitos desenvolvedores nunca chegam lá – e por causa de sua natureza low-end, existem muitos hacks ruins sobre ele. No caso de um produto, tive que reprojetar o aplicativo por causa de todos os problemas descritos em detalhes por outros; mas depois que eu limpei, nunca tive um problema de integridade de database em centenas de instalações.

Sua grande vantagem é o database de arquivo único, que é fácil de fazer backup, restaurar e copiar para o laptop para dissecar. Praticamente todas as alternativas, incluindo o sqlite (embora algumas não o admitam), exigem alguma forma de atenção do DBA de vez em quando.

Na maioria dos casos, o Access fornece bloqueios de registro e bloqueios de arquivo para alguma DDL (por exemplo, alterações de esquema) por padrão.

Mas a Microsoft está basicamente obsoleta, e alguns de seus colegas vão desprezar você por usá-la.

(Neste ponto eu normalmente me escondo e grito “INCOMING !!!”).

O access é, na verdade, uma solução de desktop para um único usuário. Na prática, tem um limite de usuário superior de “um”.

Também é um mecanismo local. Ou seja, quando você executa uma consulta, os dados são puxados pela rede para o mecanismo JET local para processamento. Um arquivo .ldb é colocado no compartilhamento de rede para controlar os bloqueios.

Se você usar um mecanismo do lado do servidor (MSSQL, MySQL, Sybase, ‘Orable etc), envie uma consulta para um mecanismo que a processe e retorne resultados para você. Bloqueios são mantidos internamente.

Isso tem enormes implicações para desempenho, estabilidade e integridade de dados.

Se o seu usuário decidir pressionar o botão de redefinição, o database do Access tem uma boa chance de ser corrompido e você terá que excluir o arquivo .ldb.

Com um mecanismo de database adequado (MSSQL, Sybase, ‘Orable: eu não gosto de backups do MySQL), então você também tem uma capacidade de backup adequada. A menos que você tenha algum software para fazer backup de arquivos em uso, é possível que você não tenha nenhum backup de seus dados no database do Access.

Eu mencionei bloqueios especificamente porque um mecanismo de database pode lidar com simultaneidade e transactions com muito mais eficiência e elegância do que qualquer sistema baseado em arquivos.

Eu posso ver usando um projeto do Access como um front-end para um mecanismo de database, mas não investindo em um aplicativo cliente completo com um back-end do Access.

Eu tenho usado o Access, ou mais propriamente, o Jet como um back-end em um site muito pequeno e privado que nunca pode crescer, pois é limitado pelo tamanho de uma profissão neste pequeno país. Em três anos não tive nenhum problema. Há menos de 100 usuários, com cerca de trinta a quarenta usando todos os dias. As tabelas têm alguns milhares de registros.

Eu não tenho muita experiência com o Access, mas este link pode ser útil para você:

http://office.microsoft.com/pt-BR/access/HP052408601033.aspx

“Você pode colocar todo o database do Access em um servidor de rede ou em uma pasta compartilhada. Esse é o método mais fácil de implementar. Todos compartilham os dados e usam os mesmos formulários, relatórios, consultas, macros e módulos. Use essa estratégia se quero que todos usem o database do Access da mesma maneira ou se você não puder suportar usuários criando seus próprios objects. ”

Quando você abre um arquivo de database do Access (.mdb) no modo compartilhado, o Microsoft Access também cria um arquivo de informações de bloqueio (.ldb) com o mesmo nome de arquivo (por exemplo, Northwind.ldb) e na mesma pasta que o arquivo de database Esse arquivo de informações de bloqueio armazena o nome do computador (como mypc) e nome de segurança (como Admin) de cada usuário compartilhado do database.Unso Microsoft Access usa essas informações para controlar a simultaneidade.Na maioria dos casos, o Microsoft Access exclui automaticamente as informações de bloqueio arquivo quando o último usuário fecha o arquivo de database. ”

O access deve ser multiusuário – eu acho que a Microsoft recomenda isso para até 4 ou 5 usuários, mas na prática eu recomendo que você nunca use um database do Access onde haja mais de um usuário, embora se você realmente não não tem escolha, é aceitável para dois ou três, dadas certas condições.

Eu tive experiência de quatro ou cinco sistemas usando um back-end do database do Access – todos adquiridos de outros ‘desenvolvedores’ – e em todos os casos eu os movi para o SQL Server como prioridade após quaisquer atualizações e correções necessárias ao aceitar o contrato – geralmente assim que eu podia falar com o chefe pagando a conta. O intervalo de tempo para isso geralmente é de vários meses, então eu o vi rodando simultaneamente por um período de tempo razoável sob vários aplicativos diferentes.

Na verdade, ele geralmente funcionará razoavelmente bem se o sistema não tiver muitas inserções / atualizações simultâneas e não for muito usado. Os principais problemas práticos da minha experiência são …

  1. É passível de corrupção – apenas acontece. Geralmente isso não é um grande problema, já que abrir o arquivo e executar o compact e o reparo resolverá os problemas, mas um bom regime de backup é absolutamente essencial.

  2. É lento. Toda vez que atualizei um sistema para o SQL Server, recebi muitos elogios por acelerar o sistema dos usuários.

  3. O arquivo de database incha por causa da maneira como o Access marca os registros como atualizados ou excluídos. Isso diminui ainda mais o sistema, pois o arquivo precisa ser carregado pela rede. Consequentemente, algum regime que comprime os dados, geralmente em uma base diária, é essencial.

Todos os itens acima são muito menos problemáticos com sistemas de usuário único, já que os problemas subjacentes que os induzem são muito menos proeminentes.

Em suma, devo enfatizar que nunca recomendaria o Access para nenhum sistema multiusuário. No entanto, se você realmente tiver também, você provavelmente conseguirá usá-lo, desde que seja um aplicativo pouco usado e você instale os procedimentos de backup e manutenção.

Já foi dito várias vezes para usar uma plataforma de database multiusuário e gratuita. Mas uma das razões pelas quais não foi dito. Isso ocorre porque, quantos bancos de dados existentes, problemáticos, problemáticos e grandes do Access começaram como “alguns registros, um ou dois usuários no máximo”? Eu arriscaria dizer todos eles.

A menos que haja apenas dois ou três funcionários em toda a empresa, as probabilidades são de que, se você desenvolver um software útil, ele acabará sendo usado por mais de dois ou três usuários originais, e terá mais do que alguns milhares de registros originais. e se expandirá ao longo dos anos para include muitos formulários, muito mais tabelas e muito mais dados. Você não pode refazer a fundação de uma casa depois que a casa for construída. Construa uma base sólida hoje e você pode expandir a casa para o conteúdo do seu coração. O mesmo para o software.

Ao ir com um compartilhamento de rede eu iria com um database de rede habilitado (mysql / firebird / mssql) em vez de access.

Para a situação, sua descrição usando o Access não seria um problema.

Eu usei o Access em situações mais desafiadoras do que isso, principalmente quando se trabalha com sites quando o Access não é abusado além da medida que realmente não é tão ruim de um mecanismo de database. (não falando de formulários e coisas assim apenas tabelas e registros)

Quando você faz inserções / atualizações / exclusões de vários usuários ao mesmo tempo, fica um pouco complicado. Este é o ponto em que você começa a pensar em mecanismos de database reais.

Além disso, quando você quer um database de baixa sobrecarga que é thread-safe, você pode dar uma olhada no vistadb (mais lento, em seguida, o access, nem sempre é gratuito, 100% .net)

Eu acho que o access usa bloqueios de nível de tabela com algum tipo de mecanismo de queing as coisas devem funcionar ok. Se você está preocupado com isso, você pode sempre fazer um teste de estresse simulado.

Eu acho que você pode defini-lo em sua seqüência de conexão de aplicativo .net. Eu pesquisei por JET, access e registro de bloqueio

aqui está um link que pode ajudar.

Por favor, veja a resposta aceita para obter detalhes reais sobre como o Access e o JET obtêm dados.

Por favor, não use o Access para um cenário multiusuário.

Acabei de passar por duas semanas de dor porque meu predecessor em um projeto escolheu o Access como back-end.

Razões concretas:

  • Não existe o Linq-to-Access
  • O Access tem inúmeras peculiaridades, como dependencies na ordem de adição de parâmetros, a comandos que levarão você para depurar.
  • O access não é escalável
  • Atualizações de database são uma tarefa quando comparadas ao uso do SQL Server