Każda komenda wewnątrz funkcji serialize()
gwarantuje wykończenia wykonywania przed rozpoczęciem następnego jeden.
W twoim przykładzie CREATE TABLE
zakończy się przed uruchomieniem INSERT
. Jeśli nie używasz serialize()
, wówczas instrukcje CREATE TABLE
i INSERT
będą uruchamiane równolegle. Zaczęliby tak szybko jeden po drugim, że INSERT
może faktycznie zakończyć się przed utworzeniem tabeli, dając błąd podczas próby wstawienia danych do tabeli, która nie istnieje.
To się nazywa stan wyścigu, ponieważ za każdym razem, gdy uruchamiasz program, możesz otrzymać innego zwycięzcę. Jeśli wygra wyścig CREATE TABLE
, program będzie działał poprawnie. Jeśli jednak wyścig wygra INSERT
, program zostanie zerwany z błędem. Ponieważ nie możesz kontrolować, kto wygra wyścig, serialize()
zatrzyma INSERT
od nawet do momentu, aż CREATE TABLE
osiągnie koniec, zapewniając, że za każdym razem uzyskasz taki sam wynik.
W twoim drugim przykładzie z tylko jednym stwierdzeniem wciąż wymagane jest serialize()
. Dzieje się tak, ponieważ run()
uruchamia zapytanie SQL, ale natychmiast zwraca, pozostawiając zapytanie do uruchomienia w tle. Ponieważ twoja następna komenda to jedna do bazy danych, zostanie ona wyłączona, gdy zapytanie będzie nadal działać.
Ponieważ serialize()
nie zwraca, dopóki nie zakończyło się ostatnie z wewnętrznych zapytań, korzystanie z niego zatrzyma się na close()
, dopóki zapytanie nie zostanie zakończone.
Jeśli używasz innego typu zapytania (np. W odpowiedzi na kliknięcie przycisku na stronie internetowej, gdzie baza danych pozostaje otwarta między połączeniami), prawdopodobnie nie będziesz potrzebował serialize()
. Zależy tylko od tego, czy kod następujący po każdym zapytaniu wymaga, aby kwerendy przed nim zakończyły się, czy też nie.
Przy podejmowaniu decyzji, czy używać serialize()
, czy nie, pomocne może być wymyślanie dowolnych zapytań niemumerowanych, tak jakby były one komentowane, a następnie sprawdzanie, czy kod nadal działa. W powyższym pierwszym przykładzie usunięcie polecenia CREATE TABLE
spowodowałoby złamanie następującego oświadczenia INSERT
(ponieważ wtedy nie byłoby tabeli do wstawienia), dlatego te muszą być serializowane. Ale jeśli masz dwie komendy CREATE TABLE
, usunięcie jednego nie wpłynie na inne, więc te dwie komendy nie muszą być serializowane.
(Ta porada nie ma zastosowania do close()
jednak - Zasadą jest, aby wywołać tylko close()
raz wszystko zakończy uruchomiony.)
Prawdopodobnie jednym z powodów: http://stackoverflow.com/a/18899872/1936319 – Sizzler