sql >> Databáze >  >> RDS >> SQLite

Problém s pamětí SQLite s přístupem singleton

Pokud se vám zobrazuje zpráva, že je otevřeno příliš mnoho souborů, příčinou může být příliš mnoho kurzorů, které jsou stále otevřené.

Vrácená zpráva však nemusí být vždy stejná a pravděpodobně je specifická pro volaný úkol/volání.

V tomto případě byla zpráva (unable to open database file (code 2062)) , ještě v jiném případě (z SELECT byla zpráva unable to open database file (code 14) ). SQLite nemůže otevřít databázový soubor (kód 14) při častém dotazu „SELECT“.

Výše uvedený odkaz také odkazuje na příspěvek, který jsem vytvořil, což zcela jasně ukazuje, že vytvoření kurzoru vede k otevření souboru (nebo souborů).

Příklad procházel asi 500 řádky a pro každý řádek vytvářel/znovuvytvářel 3 kurzory pro každý řádek (takže potenciálně 1500+ kurzorů, i když byly použity pouze 4 objekty kurzoru).

Zpočátku to bylo pouze zavírání 3 kurzorů na konci (poslední řádek rodiče ze všech), což vedlo k tomu, že unable to open database file (code 14) . Zavřením 3 kurzorů pro každou iteraci byl problém vyřešen.

Kód, který selhal, byl :-

        SQLiteDatabase db = getWritableDatabase();
        Cursor shoplistcursor = getAllRowsFromTable(SHOPLIST_TABLE_NAME);
        Cursor productcsr;
        Cursor aislecsr;
        Cursor prdusecsr;
        while(shoplistcursor.moveToNext()) {
            productcsr = getProductFromProductId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            aislecsr = getAisleFromAisleId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)));
            prdusecsr = getProductUsage(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)),
                    shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            if (productcsr.getCount() < 1 | aislecsr.getCount() < 1 | prdusecsr.getCount() < 1) {
                deleteShopListEntry(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_ID)));
            } 
            if(shoplistcursor.isLast()) {
                prdusecsr.close();
                aislecsr.close();
                productcsr.close();
            }
        }
        shoplistcursor.close();
        db.close();
}

Zatímco pevný kód byl :-

        SQLiteDatabase db = getWritableDatabase();
        Cursor shoplistcursor = getAllRowsFromTable(SHOPLIST_TABLE_NAME);
        Cursor productcsr;
        Cursor aislecsr;
        Cursor prdusecsr;
        while(shoplistcursor.moveToNext()) {
            productcsr = getProductFromProductId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            aislecsr = getAisleFromAisleId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)));
            prdusecsr = getProductUsage(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)),
                    shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            if (productcsr.getCount() < 1 | aislecsr.getCount() < 1 | prdusecsr.getCount() < 1) {
                productcsr.close();
                aislecsr.close();
                prdusecsr.close();
                deleteShopListEntry(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_ID)));
            } else {
                productcsr.close();
                aislecsr.close();
                prdusecsr.close();
            }
        }
        shoplistcursor.close();
        db.close();
    }

Mám tendenci se nyní řídit následujícím pravidlem/cvičením:-

  • Pokud právě dostanete výsledek např. získat počet řádků, zavřete kurzor v metodě.

  • Pokud použijete kurzor pro zobrazení, např. ListView a poté zavřete kurzor v onDestroy aktivity metoda.

  • Pokud použijete kurzor pro to, co nazývám složitějším zpracováním, např. smažete řádky se základními referencemi a poté zavřete kurzory, jakmile s tím skončíte, ve smyčce (cyklech) zpracování.



  1. SQL, Manipulace s prázdnými buňkami

  2. GROUP_CONCAT ORDER BY

  3. mysql_num_rows():zadaný argument není platným zdrojem výsledků MySQL

  4. Top 10 zajímavých faktů a tipů o MySQL