2014-12-24 11 views
5

Potrzebuję odczytać niektóre dane z bazy danych podczas ładowania niektórych danych w innym wątku z transakcji.Przeczytaj dane sqlite, gdy transakcja jest uruchomiona (Android)

Wszystkie moje wątki do odczytywania innych tabel są zatrzymywane do momentu zakończenia transakcji w innym wątku.

Potrzebuję być w stanie odczytać informacje z bazy danych bez martwienia się o inny wątek.

Przeczytałem wiele informacji na temat sqlite, android ... ale nic nie działa, zawsze moje zapytanie o odczyt parametrów jest zablokowane.

Śledziłem to jako @KevinGalligan mówi w tym wątku (What are the best practices for SQLite on Android?) rozwiązywanie blokad i innych problemów.

1) Używam tylko jeden SQLiteOpenHelper (Singleton)

2) Nigdy nie zamykając bazy

ja próbowałem:

rozpocząć transakcję z:

database.execSQL("begin immediate transaction"); 

lub

database.beginTransactionNonExclusive(); 

zamiast

database.beginTransaction(); 

Nie działa, zapytanie zablokowany.

Czytałem o WAL (database.enableWriteAheadLogging()), ale muszę wspierać api 9.

Wszelkie inne rozwiązania, aby przeczytać tymczasem transakcja aktualizuje niektóre tabele? Nie obchodzi mnie, że moje informacje są przestarzałe, ważniejsze jest, aby nie blokować moich wątków.

Odpowiedz

5

Rozwiązałem problem.

Poszedłem za tym krokiem.

Aby rozwiązać problem blokowania bazy danych i wykorzystania wielowątkowości bazy danych (z siedzibą w http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection):

1) Używam tylko jeden SQLiteOpenHelper (singleton).

2) Nigdy nie zamykaj bazy danych.

Aby móc czytać i pisać bez blokowania moje pytania I po tej czynności:

Używaj database.enableWriteAheadLogging() (tylko API> = 11), moim błędem było to, że trzeba włączyć ten tryb w wszystkich połączeń, a nie tylko w twojej transakcji lub twoich pismach, więc dodałem poniższy kod do mojej klasy openHelper w metodzie "onOpen". Oparty na tym kodzie Mozilli w github (https://github.com/mozilla/mozilla-central/blob/9f2b8297b99d9d28038256b4f92a5aaa941749f1/mobile/android/base/db/TabsProvider.java).

Dzięki temu rozwiązaniu rozwiązałem problem blokowania odczytów podczas aktualizacji niektórych tabel, ale inne aktualizacje są również blokowane. Jeśli chcesz rozwiązać ten ostatni problem, jak @commonsware mówi:

przy użyciu yieldIfContendedSafely() wewnątrz transakcji dajesz innym wątkom szansę pracy z bazą danych. Nie widziałem żadnej różnicy przy użyciu tej metody z beginTransaction lub beginTransactionNonExclusive.

Innym ciekawym odczytu jest: What are the best practices for SQLite on Android?

3

Myślę, że powinieneś używać koncepcji synchronizacji, aby uniknąć problemów, przed którymi stoisz.

+0

Synchronizacja jest uniknięcie warunków wyścigu, etc ... To będzie dodać kolejne problemy blokujące do mojego przypadku ... I tylko trzeba czytać bazy danych, nie martwiąc się, czy jestem aktualizacją stół. – culebrins

+0

w takim przypadku będziesz musiał umieścić własną logikę. – SAM

1

SQLite w Androidzie nie jest bezpieczny dla wątków, baza danych zostanie zablokowana podczas wykonywania operacji, co oznacza, że ​​powinieneś upewnić się, że operacja bazy danych jest wykonywana tylko w jednym wątku, i wywołać database.setTransactionSuccessful(); aby zakończyć transakcję po zakończeniu pracy.

1

Jeśli ładowanie danych nie jest tylko jedną masową transakcją SQL, use yieldIfContendedSafely(), aby umożliwić innym wątkom odczytywanie bazy danych w różnych punktach. Na przykład, jeśli wykonujesz jakieś masowe ładowanie danych i wykonujesz transakcję co 100 wstawek, wywołaj yieldIfContendedSafely() w każdym przejściu pętli every-100-insertts, aby dać innym wątkom szansę pracy z Baza danych.

Powiązane problemy