2010-03-07 15 views
16

Zajmuję się tworzeniem aplikacji dla systemu Android. Ma wiele wątków odczytywanych i zapisujących w bazie danych SQLite Android. Otrzymuję następujący błąd:Jak uniknąć błędów blokowania SQLiteException

SQLiteException: error code 5: database is locked

rozumiem SQLite blokuje całą db na Wkładanie/aktualizacji, ale błędy te tylko wydają się zdarzyć podczas wstawiania/aktualizacji podczas gdy biegnę kwerendę wybierającą. Zapytanie select zwraca kursor, który jest otwarty dość mocno (kilka sekund kilka razy), podczas gdy I iteracji nad nim. Jeśli kwerenda wyboru nie jest uruchomiona, nigdy nie otrzymam blokad. Jestem zaskoczony, że wybrany może zablokować db. Czy to możliwe, czy dzieje się coś innego?

Jaki jest najlepszy sposób na uniknięcie takich zamków?

+0

można powiedzieć pozostawiając kursor otwarte na chwilę. Uważam, że mam ten sam problem, ale moje kursory są obsługiwane przez listView. Czy zdołałeś kiedyś to naprawić? – taer

+1

Tak Naprawiłem to poprzez natychmiastowe odczytanie zawartości kursora w kolekcji, zamknięcie kursora, a następnie iterację nad kolekcją, aby wykonać czasochłonną pracę. Jeśli używasz listView, powinieneś móc zrobić to samo i użyć ArrayAdapter lub napisać własny adapter rozszerzający ArrayAdapter. – TheArchedOne

+0

http://stackoverflow.com/questions/7657223/sqlite-exception-database-is-locked-issue/9503044#9503044 – junto

Odpowiedz

2

Unikając pozostawiania kursorów otwartych przez "dłuższy czas". Jeśli możesz pozwolić sobie na wszystkie swoje dane w pamięci wszystkie na raz, to zrób to.

Jeśli nie możesz, spróbuj zwiększyć zajętość limitu czasu.

1

Migracja do obiektu ContentProvider zamiast bezpośredniego dostępu do bazy danych. ContentResolver usuwa wszystkie problemy związane z wątkami, a także pozwala korzystać z innych przydatnych funkcji, takich jak udostępnianie danych między aplikacjami lub synchronizacja z serwerem.

Obciążenie api dla ContentResolver jest minimalne. Trzeba tylko zdefiniować ciąg AUTORYZOWANY (Unikalny ciąg identyfikujący "rodzaj" danych - użyj typu "com.example.myapp.contacts") i użyj ContentResolver.bla zamiast db.bla.

7

Prawdopodobnie otwierasz i zamykasz wiele połączeń z bazą danych w różnych wątkach. To jest zły pomysł. Po prostu otwórz jedno połączenie z bazą danych i korzystaj z niego ponownie; SQLite zapewni poprawne serializowanie dostępu współbieżnego.

Podobnie jak w przypadku odpowiedzi jcwenger, używanie ContentProvider to inny sposób na osiągnięcie tego, ale będzie wymagać znacznie bardziej uciążliwych zmian w kodzie.

+0

Nie otwieram i nie zamykam bazy danych wiele razy, chociaż otrzymuję ten błąd, weź patrz [link jest tutaj] (http://stackoverflow.com/questions/13859840/application-crashes-on--instalacji-z-błędem-sqlite3-exec-failed-to-set-sync) – MobileEvangelist

0

Jego spowodowane beginTransaction() function.Look w kodzie, problem został rozwiązany dla mojej aplikacji do tworzenia linii komentarz funkcja ta (beginTransaction) linia

Powiązane problemy