OleDbException (0x80004005): Byl překročen limit systémových prostředků   otázka

VB.NET, Databáze

Zdravím,

potřeboval bych nutně poradit s chybou, která vzniká při opětovném připojování k databázi Access. K databázi přistupuji postupem níže.

        Dim assemblyLocation As String = frmKP.GetType().Assembly.Location
        Dim position As Integer = assemblyLocation.LastIndexOf("\")
        Dim accessStringTemplate As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + assemblyLocation.Substring(0, position) + "\Data\database.accdb;Persist Security Info=True"

        conn = New OleDbConnection(accessStringTemplate)
        conn.Open()

Během chodu programu používám různé operace s databází, po jejichž vykonání databázi vždy uzavřu. Například:

    Public Function ReadNumberValue(ByVal sqlQuery As String, ByVal pole As String) As Integer

        ConnectGDB()
        Dim oleDbCommand As OleDbCommand = New OleDbCommand(sqlQuery, conn)
        Dim oleDbDataReader As OleDbDataReader = oleDbCommand.ExecuteReader()
        Dim value As Integer = 0
        Do While oleDbDataReader.Read()
            value = oleDbDataReader(pole)
        Loop
        conn.Dispose()

        Return value

    End Function

Tento způsob byl úspěšně otestován na několika PC. Bohužel při finálním nasazení aplikace v konkrétním počítačovém ekosystému dochází jednou za čas k chybové hlášce - OleDbException (0x80004005): Byl překročen limit systémových prostředků. Zkusil jsem aplikaci na více těchto PC se stejnou hardwarovou i softwarovou konfigurací a chování bylo stejné.

Zkusil jsem následně malou změnu v kódu, kdy místo neustálého otvírání a zavírání databáze jsem se připojil pouze jednou po dobu chodu aplikace, nicméně to nepomohlo.

Tušíte v čem by mohl být problém? Nemám se čeho chytit, netuším jak celou věc řešit. Každá rada bude dobrá.

Jsem amatér, tzn. pokud potřebujete více informací pro rozřešení problému, ptejte se prosím.

Děkuji.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Proč nepoužíváte pro připojení do DB using blok? Ten dispose se mi nezdá nejvhodnější způsob

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Děkuji za tip, jen si nejsem jistý, jestli to vyřeší můj problém, to se dozvím až při dalším testování v pondělí, takže se ozvu s výsledkem. Změna bude každopádně v tom, že jsem předtím nikdy neuvolňoval paměť pomocí Dispose u OleDbCommand.

V každém případě jsem provedl náhradu za Using v celém kódu aplikace. Teď přístupy do databáze vypadají takto:


    Public accessStringTemplate As String = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
        "Data Source=" + frmKP.GetType().Assembly.Location.Substring(0, frmKP.GetType().Assembly.Location.LastIndexOf("\")) + "\Data\database.accdb;" & _
        "Persist Security Info=True"

    Public Sub SetValue(ByVal sqlQuery As String)

        Using conn = New OleDbConnection(accessStringTemplate)
            conn.Open()
            Using cmd As New OleDbCommand(sqlQuery, conn)
                cmd.ExecuteNonQuery()
            End Using
        End Using

    End Sub

   "nebo

   Public Function ReadNumberValue(ByVal sqlQuery As String, ByVal pole As String) As Integer

        Dim value As Integer = 0

        Using conn = New OleDbConnection(accessStringTemplate)
            conn.Open()
            Using cmd As New OleDbCommand(sqlQuery, conn)
                Dim oleDbDataReader As OleDbDataReader = cmd.ExecuteReader()
                Do While oleDbDataReader.Read()
                    value = oleDbDataReader(pole)
                Loop
            End Using
        End Using

        Return value

    End Function

Pokud Vás napadá ještě jiný důvod, proč by mělo docházet k chybovým hláškám, budu vděčný za další radu.

Pro úplnost chybové hlášení zde: https://dl.dropboxusercontent.com/u/4984...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Na kolika PC to najednou běží? Databáze se používá jedna pro všechny PC? Na jakém stroji je DB uložena?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Děkuji za reakci. Po testování je chování stále stejné.

Jedná se o desktopové řešení, kdy databáze lokálně obsluhuje aplikaci na daném PC. Čtení z databáze a zápisů do ní je velké množství v krátkém časovém sledu.

Trochu víc jsem teď o víkendu pátral a narazil jsem na zřejmě identický problém. Stejně jako u něj se chyba objevuje náhodně:

http://stackoverflow.com/questions/13484...

Závěr uživatele je ten, že Access i po uzavření připojení zřejmě neumí uvolnit všechny zdroje. Nejsem si jistý, jestli jsem správně pochopil jeho řešení. Sám jsem testoval otevřít databázi pouze jednou, nechal ji tak celou dobu a dále jen používal různé funkce a procedury volající OleDbCommand s SQL příkazy, což se neosvědčilo...

Jak jsem avizoval, jsem amatér. Takže Vás požádám o radu, jak byste k řešení přistoupili na mém místě. Není náhodou vhodnější použít úplně jiný formát databáze (popř. jaký)? :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Taky jsem amatér. Otevřít databázi "na furt" po celou dobu běhu programu není dobrý nápad. Přístup do DB by měl být otevřen pouze na nezbytně nutnou dobu. Nicméně si myslím, že MS Access není stavěn na velké množství dat a vstupy a výstupy v krátkých časových intervalech. Ve Vašem případě bych zcela určitě volil nějakou SQL databázi. V podstatě pokud to má být DB "u aplikace" na konkrétním stroji, by se dala použít databáze *mdf která se pak přiloží k aplikaci...

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Mě ti tam člověče chybí uzavření oleDbDataReaderu, který tam vytváříš.

Zkus funkci ReadNumberValue takhle

    Public Function ReadNumberValue(ByVal sqlQuery As String, ByVal pole As String) As Integer

        Dim value As Integer = 0

        Using conn = New System.Data.OleDb.OleDbConnection(accessStringTemplate)
            conn.Open()
            Using cmd As New System.Data.OleDb.OleDbCommand(sqlQuery, conn)
                Dim oleDbDataReader As System.Data.OleDb.OleDbDataReader = cmd.ExecuteReader()
                Do While oleDbDataReader.Read()
                    value = oleDbDataReader(pole)
                Loop
                ' ----- UZAVŘÍT DataReader -----
                oleDbDataReader.Close()
            End Using
        End Using

        Return value

    End Function
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nikdy jsem DataReader neuzavíral, ale taky jsem nepoužíval

Do While
Loop

ale

While Datareader.read
End While
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zdravím po odmlce, řešením pro mě bylo převedení formátu databáze z *accdb na starší *mdb. Zároveň jsem namísto databázového stroje Microsoft.ACE.OLEDB.12.0 použil pro připojení Microsoft.Jet.OLEDB.4.0. Problém to vyřešilo, po důvodu jsem se nepídil, nemám na to kapacity :) Zdůvodnění přenechám ostatním. V každém případě děkuji za spolupráci a rady!

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback