Jak zapewnić poprawność, gdy wiele procesów uzyskuje dostęp do jednego pliku bazy danych SQLite?SQLite3 i wiele procesów
Odpowiedz
Po pierwsze, należy unikać równoczesnego dostępu do plików bazy danych sqlite. Współbieżność jest jednym z słabych punktów sqlite, a jeśli masz bardzo współbieżną aplikację, rozważ użycie innego silnika bazy danych.
Jeśli nie można uniknąć współbieżność lub spadek SQLite, owinąć napisać transakcji BEGIN IMMEDIATE;
... END;
. Domyślnym trybem transakcji w sqlite jest DEFERRED
, co oznacza, że blokada jest uzyskiwana tylko przy pierwszej faktycznej próbie zapisu. Przy transakcjach IMMEDIATE
blokada jest natychmiast pobierana lub natychmiast otrzymujesz SQLITE_BUSY
. Gdy ktoś zablokuje bazę danych, inne próby zablokowania będą skutkować SQLITE_BUSY
.
Radzenie sobie z SQLITE_BUSY
jest czymś, o czym musisz sam zadecydować. W przypadku wielu aplikacji, oczekiwanie na sekundę lub dwie, a następnie ponowna próba działa całkiem dobrze, rezygnacja po n
nieudanych próbach. Istnieją pomoce API sqlite3, które ułatwiają to, np. sqlite3_busy_handler()
i sqlite3_busy_timeout()
, ale można to zrobić również ręcznie.
Można również użyć synchronizacji poziomu OS, aby uzyskać blokadę muteksu w bazie danych, lub użyć przesyłania komunikatów między wątkami/procesami na poziomie systemu operacyjnego w celu zasygnalizowania, kiedy jeden wątek ma dostęp do bazy danych.
Wiem, że należy korzystać z transakcji w ramach jednego procesu. Jednak w mojej sytuacji mam wiele procesów, w przeciwieństwie do wielu wątków, jednocześnie uzyskujących dostęp do tego samego DB. Czy transakcje SQLite naprawdę obsługują taką współbieżność!?!? –
@Tom: Tak, w dolnej warstwie portowania dla systemu operacyjnego sqlite3 istnieje funkcja blokowania działająca w różnych procesach. Zobacz http://www.sqlite.org/lockingv3.html dla więcej – laalto
DEFERRED w rzeczywistości oznacza, że baza danych nie jest (udostępniana) zablokowana, dopóki nie będzie dostępna przez odczyt lub zapis po instrukcji BEGIN (tak, powinna zablokować się na czytać). NATYCHMIAST oznacza, że baza danych jest zablokowana natychmiast po wykonaniu "BEGIN NATYCHMIAST TRANSAKCJI". Zobacz http://www.sqlite.org/lang_transaction.html –
Każdy prymityw SQLite zwróci SQLITE_BUSY, jeśli próbuje uzyskać dostęp do bazy danych, do której ma dostęp inny proces w tym samym czasie. Możesz sprawdzić ten kod błędu i po prostu powtórzyć akcję.
Alternatywnie można użyć synchronizacji OS - mutex na MS Windows lub coś podobnego w innych systemach operacyjnych. Proces podejmie próbę pozyskania muteksu, a jeśli ktoś inny go już posiada, proces zostanie zablokowany, dopóki drugi proces nie zakończy operacji i zwolni muteks. Należy zachować ostrożność, aby zapobiec przypadkom, w których proces nabywa muteks, a następnie nigdy go nie zwalnia.
Hmm, czy SQLite nie zapewnia blokad dostępu do bazy danych? –
SQLite FAQ o dokładnie this
Przeczytałem to FAQ, zanim opublikowałem tutaj swoje pytanie. Powinienem był to powiedzieć (była to lekcja numer dwa, której nauczyłem się dzisiaj). Nie widziałem dokładnie, co mieli na myśli. Czy mam samemu obsługiwać wszystkie blokady, czy też SQLite ma na to wsparcie? "Kiedy dowolny proces chce napisać, musi zablokować cały plik bazy danych na czas jego aktualizacji, ale zwykle zajmuje to tylko kilka milisekund, inne procesy czekają na pisarza, aby zakończyć, a następnie kontynuować swoją działalność." Wdrożenie tego wymagałoby trochę wysiłku. –
Jest to nie tylko uciążliwe, ale także podatne na błędy. Mam nadzieję, że SQLite będzie wymagało wsparcia, w takim przypadku zastanawiam się, jakie funkcje powinienem użyć. Na marginesie uważam, że dokumentacja SQLite jest nieco zbyt powściągliwa, jeśli chodzi o przykłady z kodem źródłowym ... –
https://meta.stackexchange.com/questions/225370/your-answer-is-in-another- zamek-kiedy-to-odpowiedź-nie-odpowiedź –
Zasadniczo trzeba owinąć swój kod dostępu do danych o transakcjach. Pozwoli to zachować spójność danych. Nic więcej nie jest wymagane.
W SQLite używasz
rozpocząć transakcji
dokonać transakcji
pary do oddzielania transakcji. Umieść swój kod SQL pomiędzy, aby go wykonać w pojedynczej transakcji.
Jednak, tak jak poprzedni ludzie komentowali przede mną - należy zwrócić szczególną uwagę na kwestie współbieżności. SQLite może działać dość szybko, jeśli jest używany do odczytu (wiele czytników nie jest blokowanych i może działać jednocześnie).
Jednak - obraz zmienia się znacznie, jeśli kod przeplata zapis i odczyt. Z SQLite - cały plik bazy danych zostanie zablokowany, jeśli aktywny jest nawet pojedynczy program piszący.
- 1. KyotoCabinet i wiele procesów?
- 2. Wiele powtarzających się procesów
- 3. Wiele procesów chromowania po chromedriver.quit()
- 4. Równoczesne pisanie z sqlite3
- 5. Problem rozwidlania fork() wiele procesów Unix
- 6. Jak uruchomić wiele procesów/wątków/frontendów Tornado?
- 7. COM z serwera procesów uruchamia wiele instancji
- 8. Linux: Jak znaleźć listę procesów demonów i procesów zombie
- 9. Wiele procesów uruchamiających jądra CUDA równolegle
- 10. sqlite3 i cursor.description
- 11. Jak korzystać z tej samej bazy danych SQLite3 z wielu procesów Perla?
- 12. Ile procesów i wątków zostanie utworzonych?
- 13. Intellij IDEA tworzy wiele procesów dla każdej sesji debugowania?
- 14. "Zbyt wiele zmiennych SQL" Błąd w Django witih sqlite3
- 15. Czy wiele procesów JVM może współużytkować pamięć dla wspólnych klas?
- 16. Jak opublikować wiele aplikacji/procesów za pomocą jednego wdrożenia clickonce?
- 17. Htop pokazujący wiele procesów Java z różnymi pids
- 18. plik bazy Sqlite3 przedłużenie
- 19. kolejka procesów perla
- 20. Zestaw FMResultSet sqlite3 i fmdb jest możliwy?
- 21. sqlite.cs nie może znaleźć sqlite3 i społeczności
- 22. Polecenie powłoki sqlite3 ".backup" i transakcja
- 23. sqlite3 przygotowania, oprawa i resetowanie statments
- 24. Tarło i czeka procesów potomnych w Pythonie
- 25. Czy identyfikatory wątków i procesów są unikatowe?
- 26. Android Studio: aapt.exe tworzy zbyt wiele procesów i sprawia, że Android Studio jest bardzo wolny
- 27. Wzorce dla wielu procesów PHP?
- 28. Klejnotu sqlite3-ruby nie można znaleźć sqlite3.h na ubuntu
- 29. Blokowanie sqlite3 db do pobrania pliku
- 30. sqlite3: Nie znaleziono
Przynajmniej mógłbyś oznaczyć swoje pytanie odpowiednim językiem programowania. –
Zbuduj lub określ, że potrzebujesz agnostycznego, agnostycznego, agnostycznego, wszystko-agnostyczne, bez agnostyki. – sharptooth
Chciałbym spróbować ponownie bez "pokaż mi kod" ... –