Page 1 of 2 1 2 LastLast
Results 1 to 15 of 17

Thread: tijdelijke database ontoegankelijk

Hybrid View

  1. #1
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426

    tijdelijke database ontoegankelijk

    In een onze applicaties wordt gebruik gemaakt van Access.mdb bestanden die via ADO worden benaderd met gebruik maken van de Jet-engine. Er wordt uitgebreid gebruik gemaakt van tijdelijke tabellen. Een bestaand probleem in Access is dat (tijdelijke) tabellen die tijdens een werksessie worden aangemaakt niet daadwerkelijk worden op opgeruimd. Ze verdwijnen bij een delete actie wel uit zicht maar zijn op de achtergrond nog steeds aanwezig. Als de totale filegrootte van het mdb bestand boven de 2 Gb komt is de database acuut niet meer toegankelijk. 2Gb lijkt veel maar blijkt in de praktijk regelmatig toch te worden bereikt.
    Nou biedt Access ( cq. de Jet-engine) de mogelijkheid om direct te kunnen communiceren met andere mdb-databases. Door de tijdelijke tabellen niet weg te schrijven naar de "eigen" mdb maar naar een tijdelijk aangemaakte mdb kan het probleem van het vollopen van de database worden omzeild: tijdelijke database aanmaken ( in de centrale tempmap) , tabel wegschrijven naar die tijdelijke database, tabel in de tijdelijke database openen en laden in het werkgeheugen, dataconnectie verbreken (data blijft in geheugen en toegankelijk), tabel in tijdelijke database sluiten en tijdelijke database deleten.
    Dit werkt al jaren probleemloos.
    Er zijn de laatste tijd echter enkele klanten die na de een overgang naar een "grote" Windows 10 netwerkomgeving regelmatig de fout krijgen dat de aangemaakte tabel niet toegankelijk is ; "cannot perform this operation on a closed dataset". De fout lijkt tamelijk random op te treden. Het eerste mdb-bestand opent altijd probleemloos maar bij het openen van een nieuw bestand (zonder de applicatie te sluiten) gaat het regelmatig mis. In een standalone windows10 omgeving of een win10 mininetwerkje is er geen enkel probleem. Ik kan er de vinger niet achter krijgen.

    Wat kan daarvan de oorzaak zijn?
    - iets in het tempmanagement ( centrale tempdir vs applicatie tempdir vs persoonlijke tempdir oid) van win10 al dan niet in combinatie met de toegangsrechten van de gebruiker ?
    - een oledb-driver in de nieuwe omgeving die roet in het eten gooit ( maar waarom dan in een gewone/kleine omgeving niet) ?
    - het ongewild poolen van dataconnecties?

    iemand een suggestie?

  2. #2
    Wat is de "centrale tempmap" ?

    Is dat de %temp% map (uniek voor elke gebruiker)?
    Of heb je zelf ergens een "tempmap" gemaakt?

    Wat is een "grote" Windows 10 netwerkomgeving?
    Bedoel je gewoon meerdere werkstations (zou geen invloed mogen hebben op die tempmap).
    Of bedoel je een terminal server (waar de sessies allemaal op de server lopen)?

  3. #3
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    @ RVK:
    De applicatie gebruikt de windows function GetTempPath(MAX_PATH, @tempFolder) om een tijdelijk pad op te vragen
    De executable staat centraal op de server en de gebruikers starten de applicatie via een snelkoppeling op hun werkstation

  4. #4
    GetTempPath geeft inderdaad de %temp% terug dus die is uniek per gebruiker (en op zijn eigen werkstation).

    Omdat je een "cannot perform this operation on a closed dataset" krijgt denk ik dat je wat debug-regels in moet gaan bouwen. Voordat je deze melding krijgt is er n.l. al eerder een error geweest op het openen van de dataset (je probeert hier iets met een dataset te doen maar het openen is mislukt). Als je bij/na het openen controleert wat de daadwerkelijke foutmelding is kom je misschien een stuk verder. Dus na elke Active := true of Open controleren of de dataset open is en zoniet, dan met LastWindowsError o.i.d. opvragen wat het probleem was.

  5. #5
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    De procedure om de vers aangemaakte tabel in de vers aangemaakt tijdelijke datebase expliciet te openen is voorzien van een try/except block met een specifieke boodschap:
    Delphi Code:
    1. on e: exception do showmessage('fout bij het laden van tabel xxxx:' + e.message)
    .
    Dié procedure geeft geen fout, maar vervolgens verschijnt er wel een standaard systeemfout die zegt dat de betreffende dataset niet open staat

  6. #6
    Je kunt voor de actie die je uitvoert (die die foutmelding geeft, een INSERT ofzo?) een controle op Active doen.

    Delphi Code:
    1. if not Active then raise Exception.Create('De dataset is gesloten');

    Als dat dan inderdaad voorkomt zul je ditzelfde moeten doen direct na de Active := true;

    Of misschien dat in de tussentijd iets ervoor zorgt dat de dataset gesloten wordt.
    Bijvoorbeeld een Transaction.Commit wil nog wel eens ALLE tabellen sluiten waar die transaction aanhangt.

  7. #7
    *+E13818MU01F0F* Norrit's Avatar
    Join Date
    Aug 2001
    Location
    Landgraaf
    Posts
    967
    GetTempPath geeft inderdaad de %temp% terug dus die is uniek per gebruiker (en op zijn eigen werkstation).
    Dat is ook een gevaarlijke aanname, die kun je namelijk zelf instellen. 9 van de 10 keer is dat wel zo, maar ik kan daar net zo hard een gedeelde map teruggeven.

    Verder heb ik in het verleden wel issues gehad met file-based databases in temp mappen welke niet op hetzelfde werkstation draaiden. Dat was eigenlijk allemaal SMB gerelateerd, maar uitte zich in corrupties omdat we dit niet in memory hielden.

    En heb je eigenlijk 1 of meerdere terminal servers? Afhankelijk van de opbouw van je applicatie kun je op 1 of 2 uitkomen namelijk. Dit kan ook soortgelijk gedrag veroorzaken.

    Kortweg, de omgeving waar het nu fout gaat is anders dan wat je toch nog toe gewend bent. Maar zonder hier verdere info over te krijgen blijft het gokken in het donker. En na het lezen van dit alles weet ik nog steeds niet wat je verstaat onder "een "grote" Windows 10 netwerkomgeving"
    Objective reality is a delirium caused by lack of alcohol in blood

  8. #8
    Een stapje terug:

    Access ruimt gealloceerde ruimte in MDB's inderdaad niet zomaar op, maar dat kan wel m.b.v. de JET engine.

    De optie zit ook in Access zelf, en heet Compact and Repair. Deze handeling (of een vergelijkbare) kan ook programmatisch gedaan worden. Schijnbaar kan het automatisch van binnenuit, met VBA.

    Vanuit Delphi kan het ook, volgens SwissDelphiCentral:

    Delphi Code:
    1. {
    2.   Here is a function I have made to compact and repair an access database.
    3.   Exclusive access to the DB is required!!
    4. }
    5.  
    6. uses
    7.   ComObj;
    8.  
    9. function CompactAndRepair(DB: string): Boolean; {DB = Path to Access Database}
    10. var
    11.   v: OLEvariant;
    12. begin
    13.   Result := True;
    14.   try
    15.     v := CreateOLEObject('JRO.JetEngine');
    16.     try
    17.       V.CompactDatabase('Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+DB,
    18.                         'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+DB+'x;Jet OLEDB:Engine Type=5');
    19.       DeleteFile(DB);
    20.       RenameFile(DB+'x',DB);
    21.     finally
    22.       V := Unassigned;
    23.     end;
    24.   except
    25.     Result := False;
    26.   end;
    27. end;

    Ik denk wel dat je de database hiervoor moet locken, dus het zal geen optie zijn als deze 24 uur per dag door meerdere mensen in gebruik is, maar als je een periodiek tijdswindow hebt waarin je de database voor jezelf hebt, dan kan je dit gewoon implementeren voor je hoofddatabase, en heb je überhaupt geen aparte databases nodig. Misschien te implementeren als vervolgstap na de dagelijkse backup?
    Als je dit met enige regelmaat doet, dan heb je geen aparte database nodig en blijft je hoofddatabase schoon en compact.
    1+1=b

  9. #9
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Niet direct on topic maar ik kan niet begrijpen waarom iemand er zou voor kiezen om access te gebruiken, er zijn toch betere alternatieven...Firebird bvb.

  10. #10
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,708
    Of gewoon SQL Server; hoef je "Alleen" je connectionstring van ADO aan te passen en
    een paar queries te tweaken (even snel gezegd).
    TMemoryLeak.Create(Nil);

  11. #11
    Voor veel databases heb je een databaseserver nodig. Access is een los bestand. Met name in kleine omgevingen kan dat nogal een voordeel zijn.
    1+1=b

  12. #12
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,708
    Maar wanneer je alweer meerdere werkplekken hebt en je database te groot begint
    te worden (de max grootte van Access is 2GB), worden je opties toch beperkter.
    TMemoryLeak.Create(Nil);

  13. #13
    Klopt, maar die 2 GB was omdat die temp tables niet opgeruimd worden. Je MDB file raakt in feite gefragmenteerd. Bij elke wijziging wordt er een nieuw blokje gealloceerd aan het eind van de file. Oude blokjes worden wel gemarkeerd als vrij, maar worden zelden of nooit weer opgeruimd. Compact & Repair is dus in feite een soort defragmentatie, en je file kan daar significant kleiner van worden.
    1+1=b

  14. #14
    Senior Member
    Join Date
    Mar 2002
    Location
    Edam
    Posts
    426
    @norrit : grote netwerkomgeving: in dit geval de netwerkomgeving van twee grote gemeenten. Het vervelende is dat het verschijnsel random op lijkt te treden

    @Videoripper,delphiwizard: Waarom Access? Tja, traditie in de sector en in ambtelijke omgevingen meestal standaard in het microsoftpakket.En de databasedriver zit ook zonder access (meestal) standaard in windows De applicatie draait op een combinatie van een clientserverdatabase ( SQL-server/Oracle) en losse Access bestanden ( inderdaad door het simpelweg kiezen van een andere connectionstring). De Access bestanden worden gebruikt als "meeneembaar" werkformat, voor standalone pc's en als uitwisselformat voor de ClientServer database. In het algemeen is de basisgrootte van max 2Gb ruim voldoende ruim.

    @ GolezTrol: De applicatie biedt de optie om een compact en repair uit te voeren maar een compact & repair werkt alleen met een gesloten database en kan dus niet tijdens een werksessie worden uitgevoerd. In de meeste gevallen is de ruimte groot genoeg voor een flinke portie rotzooi maar met de wat grotere projecten loopt de zaak soms verrassend snel vol ( met name ook omdat de kans dat er dan met meerdere mensen aan een project gewerkt wordt toeneemt).
    Het vreemde is ook dat de klant meldt dat een paar keer compact & repair de zaak uiteindelijk (tijdelijk) oplost.... suggereert dat de inwendige structuur of een driververschil ook nog een issue kan zijn

    De fout wil maar niet optreden in de programmeer omgeving. Het aanmaken van de tijdelijk databases, het wegschrijven van de tabel en het openen van de tabel zelf geeft geen traceerbare error. Pas als geprobeerd wordt de dataset te clonen volgt de mededeling dat de dataset gesloten is.

  15. #15
    Quote Originally Posted by Willem View Post
    De fout wil maar niet optreden in de programmeer omgeving.
    Ja, dat zijn de moeilijkste bugs

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •