Desculpem-me, não fiquem bravos por eu falar de vb. Tb trabalho com aplicações web em java, mas estou realmente em apuros. Meu pescoço está por um fio !!!
Tenho um sistema desenvolvido em VB5, que utiliza um banco de dados access e que sempre rodou estável desde 98.
O código foi crescendo e agora sem mais nem menos, tem hora que os dados são atualizados e tem hora que não.
Um detalhe importante: eu não mexi em nada no codigo que executa a atualização dessas informações e sempre ocorre quando a operação é feita por uma máquina remota, normalmente XP.
Alguém poderia me dizer algo a respeito? No trecho que está dando problemas, eu realmente não mexi nada !!!
Já tentei usar comandos tipo dbRefreshCache e dbFreeLocks para que os bloqueios desnecessários sejam liberados e a atualização seja feita imediatamente, mas não adiantou, é de Lua!!! Tem hora que faz, tem hora que não, e o código é sequencial, não tem como não fazer !!!
Alguém por favor tem alguma idéia?
[quote=ViniGodoy]Qual é o tamanho do seu banco access?
O access tem sérios problemas quando o banco ultrapassa 1Gb. Já tentou fazer um backup e rodar a compactação do banco?[/quote]
Exatamente, mas já tive problemas com bancos Access com menos de 1GB, as vezes o banco ficava corrompido do nda, Na verdade você precisa Compactar e Reparar o banco, existe essa opção no Access e também da pra ser feito via código VB, não me lembro os comandos agora, mas se der uma pesquisada por Compactar e Reparar Banco Access no VB, vc encontrará bastante coisa…
Só quis dizer que acima de um Gb esses problemas ocasionais passam a ser frequentes.
Para reparar e compactar o banco dentro do próprio vb, eu fiz a seguinte funçãozinha (VB6):
Function CompactDB(database As String, Optional destination As String = "") As Boolean
On Error GoTo CompactDBWarn
CompactDB = False
Dim temp As String
'Prepare the environment
temp = App.Path & "\data\Temp!DB.mdb"
If UCase(database) = UCase(destination) Then destination = ""
If destination <> "" Then temp = destination
If Dir(temp) <> "" Then Kill temp
'Repair the database
Call RepairDatabase(database)
'Compacts the database into a temp file
Call CompactDatabase(database, temp)
If destination = "" Then
Kill database 'Delete the unpacked database
On Error GoTo CompactDBErr
FileCopy temp, database 'Copy temp renaming to database
On Error GoTo CompactDBWarn
Kill temp 'Delete the temp file
End If
CompactDB = True
Exit Function
CompactDBWarn:
Call WriteTrace(trcWarning, "CompactDB", Err.description)
Exit Function
CompactDBErr:
MsgBox "Unable to create file " & database & " file saved as " & temp
Call WriteTrace(trcError, "CompactDB", Err.description)
Exit Function
End Function
Não é problema de corrompimento do banco de dados. Essa questão eu já conhecia.
Pelo que eu percebo, é como se a máquina local buferizasse a informação, mostrando ao usuário que o dado foi atualizado, mas quem procura essa atualização de outra máquina não vê, pq na verdade não foi. Só o usuário que realizou a operação enxerga a mudança. É como se estivesse usando a memória.
Aqui na empresa, há quase 10 anos atrás, houve um problema muito sério quando alguém resolveu usar o Access como um banco de dados multi-usuário (o que ele nunca foi). Rolou um monte de cabeças aqui. Não acho que a Microsoft tenha resolvido isso desde aquela época.
[quote=thingol]
Aqui na empresa, há quase 10 anos atrás, houve um problema muito sério quando alguém resolveu usar o Access como um banco de dados multi-usuário (o que ele nunca foi). Rolou um monte de cabeças aqui. Não acho que a Microsoft tenha resolvido isso desde aquela época. [/quote]
Exatamente, a própria MS refere-se ao Access como “domestic database”. A solução definitiva para seu problema viria apenas na substituição do banco por um corporativo.
A microsoft tem o MS-SQL Server e é realmente simples migrar do access para ele (a sintaxe das queries é praticamente a mesma que a do Access). Ou você pode adquirir algo free, ou mesmo usar algum que já esteja em vigor na sua empresa…
Nossa, nunca tive problemas com bancos tão pequenos.
Uma coisa que acontecia no passado era que empresas não estavam dispostas a investir em Oracle e SQL Server, enquanto bancos gratuitos não eram tão presentes ou bem falados. E era muito prático cair na tentação do Access, pois ele vinha com o Office e obviamente a MS não divulga abertamente os problemas dele. Aliás, pelo contrário, o banco de dados de exemplo dele, o Northwind, é um exemplo de uma aplicação multi-usuário.
O fato é que o banquinho melhorou muito nas últimas versões do Jet. Ainda sim, só recomendo para uso doméstico, mono usuário e para bancos de dados pequenos.
Sei que o access não é tão confiável como um cliente-servidor, mas por aqui é mais fácil tirar dinheiro do Tio Patinhas e quando a gente faz algo certo, então não fiz mais q a obrigação e quando dá errado, a culpa é sempre do mais fraco.
O código já ficou realmente grande e onde dá problemas é numa tabela relativamente pequena.
Eu simplesmente faço um seek, se encontrar dou um Tabela.Edit, atribuo os novos valores, dou um Tabela.Update e em seguida DBEngine.Idle dbRefreshCache e DBEngine.Idle dbFreeLocks. Eles estão sendo executados dentro do controle de transações BeginTrans/CommitTrans/Rollback e estou usando DAO.
A característica mais marcante é: na maquina q efetuou a operação, a informação está atualizada. Posso fazer uma pesquisa e ver tudo certinho, mas fisicamente ela não está atualizada. Eu não faço isso por Dynaset ou SnapShot, manipulo diretamente a tabela!
Se eu não me engano, cada máquina cria uma instância do DBEngine e cada instancia irá manter o seu próprio cache. Esse cache é automaticamente atualizado na máquina em que a consulta é executada, mas não nas demais.
Nesse caso, você deve dar o refreshCache no momento em que você pesquisa dados do banco, não no momento em que você grava. Tente inverter a abordagem.
Não é problema de corrompimento do banco de dados. Essa questão eu já conhecia.
Pelo que eu percebo, é como se a máquina local buferizasse a informação, mostrando ao usuário que o dado foi atualizado, mas quem procura essa atualização de outra máquina não vê, pq na verdade não foi. Só o usuário que realizou a operação enxerga a mudança. É como se estivesse usando a memória.
Se alguém tiver uma idéia…
Valeu
Zovao[/quote]
Mas pérai, se 2 usuários acessam o sistema ao mesmo tempo, os 2 consultam os mesmos dados na mesma tela, daí um deles altera algum campo e salva, não é automaticamente que essa informação será atualizada na tela do outro usuário. Esse outro terá que reconsultar pra poder ver as mudanças.
E como você inplementou a abertura do banco, de modo exclusivo ou compartilhado?
Se as integridades referenciais do banco foram criadas um usuário não poderá alterar um registro enquanto o outro estiver alterando, uma mensagem será retornada dizendo que o registro está bloqueado.
O que está acontecendo pessoal, é que mesmo após eu ter dado o comando de “TAbela.Update” seguido de DBEngine.Idle dbRefreshCache e DBEngine.Idle dbFreeLocks, os dados não estão disponíveis para os outros usuários. A informação parece que está só no buffer de quem executou a atualização.
E outro detalhe estranho: Se esse usuário que executou o Update fechar o programa e entrar de novo, ele também verifica que as alterações dele não foram gravadas no banco de dados, ou seja, ficaram só na memória e evaporaram. O pior de tudo é que hora grava e hora não grava. Não tem uma constância.
Tô ficando louco meu, não sei mais o q fazer !!!
Se alguém tiver uma luz.